Skip to content

Commit

Permalink
Add an architecture chart to display project and platform specificity (
Browse files Browse the repository at this point in the history
  • Loading branch information
samparent97 authored Nov 21, 2024
1 parent be96e0e commit 4c0075e
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 6 deletions.
3 changes: 2 additions & 1 deletion docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
site
.venv
.venv
.bkp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 138 additions & 0 deletions docs/docs/firmware/architecture/arch_diagram.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8" pages="2">
<diagram name="Light" id="AVefi_4B2r27eV40Z59U">
<mxGraphModel dx="989" dy="582" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="850" pageHeight="1100" background="#ffffff" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="lLjQft1QgtvO7yPWeCVP-5" value="Project&amp;nbsp;&lt;span style=&quot;background-color: initial;&quot;&gt;Specific&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="280" y="130" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-6" value="Project Independent" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="500" y="130" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-7" value="Platform&lt;div&gt;Specific&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="140" y="330" width="70" height="30" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-8" value="Platform&lt;div&gt;Independent&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="135" y="210" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-13" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#dae8fc;opacity=60;" parent="1" vertex="1">
<mxGeometry x="210" y="280" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-14" value="Bindings" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" parent="1" vertex="1">
<mxGeometry x="220" y="280" width="230" height="40" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-15" value="&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;projects/Demo/Blink/platforms/stm32f767/bindings.cc&lt;/span&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;projects/Demo/Blink/platforms/raspi/bindings.cc&lt;/span&gt;&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="210" y="330" width="250" height="70" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-17" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#f8cecc;opacity=60;" parent="1" vertex="1">
<mxGeometry x="460" y="280" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-18" value="MCAL&lt;br&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;(MicroContoller Abstraction Layer)&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" parent="1" vertex="1">
<mxGeometry x="470" y="280" width="230" height="40" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-19" value="&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;mcal/stm32f767/periph/adc.h&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;mcal/raspi/periph/adc.h&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="460" y="330" width="250" height="70" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-1" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#d5e8d4;opacity=60;" parent="1" vertex="1">
<mxGeometry x="210" y="160" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-9" value="Application Code" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" parent="1" vertex="1">
<mxGeometry x="220" y="160" width="230" height="40" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-10" value="&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;projects/Demo/Blink/main.cc&lt;/span&gt;&lt;/div&gt;projects/Demo/Blink/bindings.h&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;labelBackgroundColor=none;textShadow=0;labelBorderColor=none;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="220" y="210" width="230" height="75" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-21" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#fff2cc;opacity=60;" parent="1" vertex="1">
<mxGeometry x="460" y="160" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-22" value="Peripheral Interfaces&lt;div style=&quot;font-size: 14px;&quot;&gt;&amp;amp; Shared Code&amp;nbsp;&lt;br style=&quot;font-size: 14px;&quot;&gt;&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" parent="1" vertex="1">
<mxGeometry x="470" y="160" width="230" height="40" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-23" value="&lt;span style=&quot;font-weight: 400; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;shared/periph/adc.h&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;shared/util/mappers/lookup_table.h&lt;br style=&quot;font-size: 10px;&quot;&gt;&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="480" y="210" width="200" height="70" as="geometry" />
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-26" value="" style="endArrow=block;html=1;rounded=0;startArrow=block;startFill=1;endFill=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="160" y="280" as="sourcePoint" />
<mxPoint x="720" y="280" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="lLjQft1QgtvO7yPWeCVP-27" value="" style="endArrow=block;html=1;rounded=0;startArrow=block;startFill=1;endFill=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="460" y="420" as="sourcePoint" />
<mxPoint x="460" y="130" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram name="Dark" id="2UDOZF7GKoJFMiVs2ryz">
<mxGraphModel dx="989" dy="582" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="850" pageHeight="1100" background="#000000" math="0" shadow="0">
<root>
<mxCell id="tRIXiKq6z88w_5JdcBh1-0" />
<mxCell id="tRIXiKq6z88w_5JdcBh1-1" parent="tRIXiKq6z88w_5JdcBh1-0" />
<mxCell id="tRIXiKq6z88w_5JdcBh1-2" value="Project&amp;nbsp;&lt;span style=&quot;background-color: initial;&quot;&gt;Specific&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="280" y="130" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-3" value="Project Independent" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="500" y="130" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-4" value="Platform&lt;div&gt;Specific&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="140" y="330" width="70" height="30" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-5" value="Platform&lt;div&gt;Independent&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="135" y="210" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-6" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#dae8fc;opacity=80;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="210" y="280" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-7" value="Bindings" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="300" y="280" width="70" height="40" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-8" value="&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;projects/Demo/Blink/platforms/stm32f767/bindings.cc&lt;/span&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;projects/Demo/Blink/platforms/raspi/bindings.cc&lt;/span&gt;&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;fontSize=10;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="210" y="330" width="250" height="70" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-9" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#f8cecc;opacity=80;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="460" y="280" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-10" value="MCAL&lt;br&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;(MicroContoller Abstraction Layer)&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="480" y="280" width="210" height="40" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-11" value="&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;mcal/stm32f767/periph/adc.h&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;mcal/raspi/periph/adc.h&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;fontSize=10;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="490" y="330" width="190" height="70" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-12" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#d5e8d4;opacity=80;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="210" y="160" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-13" value="Application Code" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="250" y="160" width="170" height="40" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-14" value="&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;projects/Demo/Blink/main.cc&lt;/span&gt;&lt;/div&gt;projects/Demo/Blink/bindings.h&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;labelBackgroundColor=none;textShadow=0;labelBorderColor=none;fontSize=10;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="240" y="210" width="190" height="75" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-15" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#fff2cc;opacity=80;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="460" y="160" width="250" height="120" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-16" value="Peripheral Interfaces&lt;div style=&quot;font-size: 14px;&quot;&gt;&amp;amp; Shared Code&amp;nbsp;&lt;br style=&quot;font-size: 14px;&quot;&gt;&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=14;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="510" y="160" width="150" height="40" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-17" value="&lt;span style=&quot;font-weight: 400; font-size: 10px;&quot;&gt;Example Paths:&lt;br&gt;&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;shared/periph/adc.h&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: normal; font-size: 10px;&quot;&gt;shared/util/mappers/lookup_table.h&lt;br style=&quot;font-size: 10px;&quot;&gt;&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=top;whiteSpace=wrap;rounded=0;fontStyle=3;fontFamily=Helvetica;fontSize=10;" vertex="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry x="480" y="210" width="200" height="70" as="geometry" />
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-18" value="" style="endArrow=block;html=1;rounded=0;startArrow=block;startFill=1;endFill=1;strokeColor=#FFFFFF;" edge="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="160" y="280" as="sourcePoint" />
<mxPoint x="720" y="280" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="tRIXiKq6z88w_5JdcBh1-19" value="" style="endArrow=block;html=1;rounded=0;startArrow=block;startFill=1;endFill=1;strokeColor=#FFFFFF;" edge="1" parent="tRIXiKq6z88w_5JdcBh1-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="460" y="420" as="sourcePoint" />
<mxPoint x="460" y="130" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Architecture

Our firmware is separated in 2 layers: application and platform.
Code in our monorepo is organized based on two binary traits: Project (ECU) Specificity and Platform Specificity.

![Architecture Organization](arch_diagram-Light.png#only-light){width=100%}
![Architecture Organization](arch_diagram-Dark.png#only-dark){width=100%}

Most of the architecture is described by the interplay in project-specific sections, i.e. the left column of this diagram.

Our project-specific firmware is separated in 2 layers:

The __application__ (app) layer describes the __what the project does__ at a high level. This includes:

Expand All @@ -14,7 +21,7 @@ The __platform__ layer __configures hardware__ to run the app code. In this laye
- :fontawesome-solid-gear: Peripheral configurations.
- :fontawesome-solid-power-off: Initialization functions.

The interface between the app and platform layers is a contract called __bindings__. This contract declares a handle for each peripheral and function required by the application. The platform _binds_ a configured peripheral or function implementation to each handle.
The interface between the app and platform layers is a contract called __bindings__. This contract declares a handle for each peripheral and function required by the application. The platform *binds* a configured peripheral or function implementation to each handle.

## Why separate these layers?

Expand All @@ -24,14 +31,14 @@ There are two major motivations for strictly separating the application and plat

Since the application code is not tied to any specific platform, it can __run on any platform__, provided that platform can fulfill the bindings contract.

I _cannot overstate_ how significant this is. Being able to arbitrarily swap platforms enables:
I *cannot overstate* how significant this is. Being able to arbitrarily swap platforms enables:

- :octicons-terminal-16: Running vehicle firmware on your local machine through its command line interface.
- :material-test-tube: Testing application code with a HIL or SIL setup.
- :fontawesome-solid-microchip: Writing portable code, should we ever change our microcontroller.
- :fontawesome-solid-gears: Simultaneously having multiple hardware configurations for the same platform.

Platform abstraction means that each device executes the _exact same_ application code. This greatly simplifies debugging:
Platform abstraction means that each device executes the *exact same* application code. This greatly simplifies debugging:

- If there is a bug when running the vehicle but the test platform works fine, then you immediately know that the vehicle platform layer was configured incorrectly.
- If all platforms have the same bug, then you know that all hardware peripherals are responding and the bug exists at the app layer.
Expand Down
2 changes: 1 addition & 1 deletion docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ nav:
- Firmware:
- firmware/index.md
- firmware/dev-setup.md
- firmware/architecture.md
- firmware/architecture/index.md
- firmware/project-structure/index.md
- firmware/compile-project.md
- firmware/flashing/index.md
Expand Down

0 comments on commit 4c0075e

Please sign in to comment.