Goals
- Simplify process of writing and maintaining CAN code across each platform
- Make it easy to update CAN messages across platforms
- Make it easy to generate boilerplate code/repeated stuff
Background and strategic fit
Managing and maintaining a list of CAN messages across various architectures (ARM, x86) and languages (Go, C, JavaScript) is going to be a pain point, as we define new messages and update existing messages. As such, it makes sense to have a centralized "source of truth" that contains the messages which generates the output for all our use cases.
Assumptions
- Developers will have access to a Unix box
- This project will live as a submodule in the projects that require it
Requirements
# | Title | User Story | Importance | Notes |
---|---|---|---|---|
1 | Easy to maintain | The codebase should be easy to maintain | Must Have | Pick a high-level language (Python) that most people already know |
2 | Easy to understand and contribute to | The codebase should be easy to understand. In addition, templates should be easy to understand and pick up. | Must Have | Pick a templating framework that is popular, well-documented and has familiar syntax (Mako) |
3 | Contains tests | There should be tests for behaviour of the build script | Should Have | Tests that test input validation on invariants For compiled languages, the compiler will error if the rendered template is bad (basically only C). |
4 | Manage CAN message definitions | Make it easy to change and manage CAN message definitions | Must Have | |
5 | Tie into our build system | Nice to Have | Treating it as a first-class citizen in our build system |
Design
Our code generation framework will leverage templating features from Mako—a robust Python template framework. Developers can specify templates in the format filename.mako.extension, which indicates that the file is a template and should be rendered. The Python script will match template files matching the pattern, and produce generated code (like C) that can be compiled and flashed onto a microcontroller.
Having templates allows developers the flexibility to write specific templates for their use case, as opposed to a particular script that only fits one use-case. Mako can also call Python functions, if one requires some more complex templating behaviour.
CAN Messages
CAN messages will be defined as Protocol Buffers. Protocol buffers are a language-agnostic way for serializing structured data, which ensures that we can define CAN messages and enforce a schema on these definitions. Most projects will deal with CAN messages in their Protobuf representation—that is, aside from the embedded C code, which will use the generated template.
Not Doing
- Windows support—may be done in the future, but priority is getting it to work on Unix + CI environments
- Validating rendered template output—this is deferred to the compiler