-
Notifications
You must be signed in to change notification settings - Fork 6
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
A perpetual WIP PR #22
Draft
d3zd3z
wants to merge
48
commits into
dt
Choose a base branch
from
hack
base: dt
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
d3zd3z
added a commit
to tangybbq/keyboard-firmware
that referenced
this pull request
Oct 18, 2024
Feedback on zephyr-lang-rust has resulted in numerous API changes. The good news is that I only have a small number of commits on top of zephyr-lang-rust to support this keyboard firmware, and all currently live in: zephyrproject-rtos/zephyr-lang-rust#22
d3zd3z
force-pushed
the
dt
branch
2 times, most recently
from
October 22, 2024 18:38
601ced8
to
d4754e1
Compare
Support the `log` crate's log macros, using Zephyr's printk mechanism. There is no filter, or deferral of messages, and it pulls in both Rust and Zephyr's string formatting, but does allow logging to work directly. This is intended as a stopgap until better logging support comes in, but is also useful in its own right for builds where Zephyr logging is disabled. Signed-off-by: David Brown <[email protected]>
This code parses the DTS file generated by the Zephyr build, along with a few entries from the generated header file, to build a representation of the device tree. There is a notion of "augments" that add various methods. This is currently just hard-coded. Signed-off-by: David Brown <[email protected]>
Blinky is a rust port of the samples/blinky application from the main zephyr repo. It performs the same function, but using the DT and GPIO abstractions provided in the zephyr::sys module. Signed-off-by: David Brown <[email protected]>
Create two modules with wrappers for Zephyr gpio and flash devices. These have no methods, but allow the DT generated code to compile, with `get_instance` methods that return these values. Signed-off-by: David Brown <[email protected]>
The is_ready method on both `Gpio` and `GpioPin` will ultimately call the underlying `device_is_ready` entry. Signed-off-by: David Brown <[email protected]>
Create wrappers for config and pin toggle on the gpios. This is enough to allow the blink app to work. Signed-off-by: David Brown <[email protected]>
Move the module declaration for the device tree up into `lib.rs` to allow insertion of allow directives to eliminate documentation warnings on the generated devicetree. Signed-off-by: David Brown <[email protected]>
Fix doc build errors by filling in missing documentation comments. Signed-off-by: David Brown <[email protected]>
Instead of hardcoding all of the augments in the code, put these augments into a data structure. Load the actual rules from a yaml file (with a future ability to extend this with per-app or per-module defined augments. Convert all of the existing hardcoded augment rules into the initial augment file.
Add constructors to the individual device types. These are unsafe, and are all referenced from the generated devicetree code.
Move all of the device implementations into a `zephyr::device` module. In this module, add a `Unique` type that supports the constructors on the device requiring a unique instance. The device tree augmentation code adds a declaration for these uniqueness markers for each instance, passing it into the constructor. Signed-off-by: David Brown <[email protected]>
Gpios in Zephyr are inherently unsafe. There is a shared controller that is not just used by the pins defined here, but extensively across various drivers. As such, make all of the gpio pin operations themselves unsafe. We can help, a little bit, to at least enforce uniqueness with the Rust drivers that use gpios by requiring them to take a mutable instance of `GpioToken`, which has a singleton getter. Signed-off-by: David Brown <[email protected]>
Signed-off-by: David Brown <[email protected]>
The hard-coded augments in augment.rs are no long used, so remove them all, and move the config version into this file to avoid needing a separate module, just for the trait. Signed-off-by: David Brown <[email protected]>
Generate a full list of nodes that are present in the given device tree, and provide a tool that build.rs in the app can use to make these active. This will allow conditionals like: #[cfg(dt = "aliases::led")] to be used, which will make it possible to handle nodes being present or not in the DTS. See a subsequent patch to the blinky sample for an example of usage. Signed-off-by: David Brown <[email protected]>
Show how an application can be conditional based on the presence of a node in the devicetree. Signed-off-by: David Brown <[email protected]>
Move this code out of the device.rs file, and into separate files for each module. Signed-off-by: David Brown <[email protected]>
The gpio device tree entries for the mps2 are defined with a `#gpio-cells` value of 1, despite these values not being interpreted by the driver, but by the devicetree code. I'm not sure if these actually work with any of the demos, as it is unclear what the macros would do with this. It doesn't give us a value to use for dt_flags. If someone wants to put in some effort to fix this, feel free. But I don't think the problem is on the Rust side. Signed-off-by: David Brown <[email protected]>
Add a simplistic uart wrapper, and drivers around it. All methods are unsafe. Signed-off-by: David Brown <[email protected]>
Add a simple wrapper for the led strip driver. Signed-off-by: David Brown <[email protected]>
Add methods for get and set of pin logical values. Signed-off-by: David Brown <[email protected]>
This isn't really quite right, as the "unique" values here are per pin, and if the pin were to be used across the system, nothing would enforce these to be unique. Signed-off-by: David Brown <[email protected]>
Add an unsafe entry to the channel code that allows the message to be allocated previously. This can be useful to send messages from interrupt context, although the message has to be pre-allocate and given to the interrupt handler. Signed-off-by: David Brown <[email protected]>
This is a special keyboard matrix type used by the bbq-keyboard firmware. It doesn't belong here, and can be moved out, once we support additional augment files. Signed-off-by: David Brown <[email protected]>
Add support for Leds, and a simple augment for the pwm drivers.
Fix the DT node names in the generated `dt_cfgs` entries to match the names of the nodes. Need to apply `fix_id` in a few places to make sure non-identifier characters are converted to underscores. Signed-off-by: David Brown <[email protected]>
Enable use of the thread analyzer, if it is enabled. Signed-off-by: David Brown <[email protected]>
Add these bindings so that app code can directly use these. Signed-off-by: David Brown <[email protected]>
Avoid cluttering the top-level sync module with specifics. Signed-off-by: David Brown <[email protected]>
The SpinMutex uses a spinlock to protect a piece of data so that it can be shared safely (with safe Rust code) between different contexts. Signed-off-by: David Brown <[email protected]>
Add an `.into_irq()` to the Uart device that turns it into an interrupt driven interface. Currently, read is implemented, with a `.try_read()` method that will try, with a timeout, to read data from the interface. The methods are all marked as 'unsafe' currently, until a more thorough safety analysis can be made. Signed-off-by: David Brown <[email protected]>
A blocking write allows us to do the write without needing an intermediate copy of the data. The thread's buffer is directly copied into the uart's fifo. To make this safe, the write call must block until all of the data has been placed in the fifo. The uart.h irq interface is a little quirky. Namely, the uart fifo can only be accessed from the irq handler. To make this possible, the drivers will implement usually a soft interrupt to the irq handler, for the initial transmission. There is also an async interface in uart.h, but numerous devices don't support it. Signed-off-by: David Brown <[email protected]>
Signed-off-by: David Brown <[email protected]>
Add a timeout parameter to the 'write' method on the UartIrq interface. The method now returns the number of bytes that were actually written. Signed-off-by: David Brown <[email protected]>
This method had a lifetime error, and allowed the inner uart to be leaked beyond its lifetime. This should prevent the returned device from outliving the UartIrq, or even being used after mutable methods on the UartIrq have been used. For now, don't even return a mutable method until we evaluate what should be permissible. This at least allows reading the line status. In addition, since the return Uart is not owned by the caller, it is not permissible to call any of the `into_*` methods. Signed-off-by: David Brown <[email protected]>
With the 'Uart' encapsulated within the `UartIrq`, having a separate field for device is redundant with the one inside of `Uart`. Remove this redundant field, and change the references to it to use the one inside the Uart. Signed-off-by: David Brown <[email protected]>
Move this specific type into its own crate. Signed-off-by: David Brown <[email protected]>
Add ring size parameters to the UartIrq type. These will later be used to migrate the interface to an async interface (not rust asyc). Signed-off-by: David Brown <[email protected]>
Update the writing to be an async interface. Instead of a blocking write, there is a `write_enqueue` to add the message, and a `write_wait` which is a blocking wait for a write to handle. For this to work, the UartIrq needs to own the buffer for the duration of the write. At this point, the buffers are just `Vec<u8>`, but a future change will make this more general, so that, for example, Pooled buffers can be used. The buffer should never be dropped within this code. Signed-off-by: David Brown <[email protected]>
Because this interface has registered IRQs, prevent drops. They are probably safe due to the use of the leaked Arc, but the data is in fact leaked. For now, just cause Drop to panic, as normal use won't ever drop this. Signed-off-by: David Brown <[email protected]>
Change the read interface to also be async. The user must enqueue one or more buffers for the driver to place data into. Signed-off-by: David Brown <[email protected]>
The result from the async_write holds the buffer, but the fields are private. Provide two accessors to make this result useful: - as_slice: returns a slice of the useful part of the buffer - into_inner: Transforms into the buffer, so it can be reused. Signed-off-by: David Brown <[email protected]>
Use the Zephyr KConfig `CONFIG_DEBUG` to determine if the Rust code should be built as release or debug. This will better optimize the code. Applications can still set options for `[profile.release]` to enable things such as run time assertions. For example, debug symbols can still be enabled with `debug = "full"`, which attempts to insert debugging information, although the optimizer can still make the code challenging to debug.o `debug-assertions = true`, and `overflow-checks = true` can still be enabled in the release builds, for some additional checks. Signed-off-by: David Brown <[email protected]>
d3zd3z
force-pushed
the
dt
branch
2 times, most recently
from
November 21, 2024 20:27
e640970
to
7e8a847
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR holds onto changes that would be considered "work in progress", but can be reviewed. Ideally, this should be based on top of other pending PRs so that the actual change here is kept minimal.
Built upon #15