Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add raltool to replace imxrtral.py #29

Merged
merged 16 commits into from
Nov 28, 2022

Conversation

mciantyre
Copy link
Member

This PR adds raltool to the repository. raltool is a fork of chiptool, which is a fork of svd2rust. The tool emits an imxrtral.py-compatible register access layer, allowing us to replace imxrtral.py.

This PR does not yet use raltool. A dependent PR will remove imxrtral.py, re-generate the RAL with raltool, and add support for the 1176 multi-core MCUs.

Why

I found that raltool could help us with issues noted in #26:

  1. Clusters and register arrays can be complex, and imxrtral.py doesn't handle that complexity.
  2. Symbols in 11xx SVDs differ from symbols in 10xx SVDs, so the HAL code isn't portable without patching.
  3. Today's imxrt-ral resource management doesn't work for all multi-core cases.

The chiptool intermediate representation made it easy to handle issue 1. The IR also made it easier to implement a new "combine" phase that consolidates peripherals across devices. The combine phase and the chiptool transforms let us solve 2 without patching SVDs to meet our project's needs.

In regards to 3: the RAL generated by raltool has no notion of resource management. This is similar to chiptool's original codegen but dissimilar to the original imxrtral.py codegen. You'll see this when studying RAL code and documentation in the next PR. We can explore resource management separately / later.

Quick testing shows that raltool-generated crates build faster than svd2rust- and chiptool-generated crates. The README has my measurements.

Upstreaming

imxrt-rs/imxrt-hal#121 proposed upstreaming the RAL codegen to chiptool. Unless people are eager to use and maintain the RAL backend within chiptool, I'd prefer to develop RAL codegen ideas here and propose them once they're tested. I'd also like time to think about separating the IR and transformers from the codegen so that codegen modules could be developed independently.

Nevetheless, I kept upstreaming in mind. Use git subtree to separate patches for contributions, and to bring in any upstream chiptool commits.

git-subtree-dir: raltool
git-subtree-split: 73b33d9
Child commits apply the patches that turn it into raltool. This merge
tracks to a commit on the chiptool master branch.

Merge commit '0ceb38148dd666895640afd1fc4e6ae265f7676c' as 'raltool'
The BitSize newtype helped with refactoring, and could be removed if
deemed too noisy. After this commit, the size of a set of fields is
based on the size of the register.

Before this commit, the registers for an MIMXRT PWM peripheral were all
incorrectly u32s. After this commit, I observed that code generated for
an MIMXRT PWM peripheral used u16 throughout. It still might use u8 for
individual fields, but that doesn't affect the MMIO register
interactions. Only tested by extracting peripherals, then generating
blocks based on the YAML output; haven't tested a full SVD -> PAC
transform, but I would expect that to work.
Combine lets us consolidate enums, fieldsets, and blocks across devices.
Given multiple IRs, combine figures out the various versions of these IR
elements, then creates a new IR that shares as much as it can. The
heuristics for combining these IR elements is encoded in the combine
module.
When a block is used across multiple peripheral instances, remove any
number suffix.
Remove the strong types, favoring a RAL-like pattern for accessing
register fields and enums. This is achieved by nesting the render calls
during codegen.
I plan to subtree this project directly into imxrt-ral. That project's
CI will cover this build.
If you discard type information, it's nice to have a way to re-acquire
the N associated with a peripheral. This commit introduces the `number`
functions for that purpose. This can let users create thin drivers just
around a register block static reference, and only acquire the
number at runtime.

Document this new function as an advanced usage, along with one other
(unrelated) usage pattern.
Hide the `steal()` method; it's only available for RTIC. Users should
call their own `instance()` methods.
@mciantyre
Copy link
Member Author

One notable raltool limitation is that it's not generating register reset values. This means that ral_registers::reset_reg! won't work with the generated code.

A follow-on PR re-generates the RAL using raltool. It revises imxrt-ral documentation, and those docs notes this limitation. Re-adding it is backwards compatible, so I was planning on tackling it later. But let me know if you think it's important to have it from the start.

@mciantyre mciantyre merged commit 0579dc7 into imxrt-rs:master Nov 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant