-
Notifications
You must be signed in to change notification settings - Fork 6
Description
- Proposed
- Prototype: Not Started
- Implementation: Not Started
- Specification: Not Started
Summary
Similar to read-only registers, we should allow for write-only and event-only registers.
Motivation
This is required to fully flesh out an asynchronous programming model inside the Harp protocol. We expect all of the following to be resolved if this proposal is accepted.
Avoid misinterpreting event messages
Currently, if a register represents a "pure" event, i.e. an event with no state, we have the following problems:
- Reads of the register are meaningless and at best represent the potential for the firmware developer to introduce inconsistent state.
- Because the register is still a read register, it is included in the initial state dump. If the host is not careful to filter out specifically for event registers, this message can be incorrectly interpreted as an "event" and generate off-by-one errors when pairing with other data, etc.
Allow pure function calls
Currently, a register represents state + function, but sometimes we just want to trigger a function and the "state" is only valid as the input argument to the function. Currently we have no option but to make such temporary call state readable, which creates the following problems:
- Reads of the register are meaningless and at best might represent stale arguments from a previous call.
- The register will be included in the initial register dump which is also misleading as it may give the impression this is some kind of "configuration" variable, where in reality there is no such thing.
Allow async / await function calls
Implementing both write-only and event-only registers would allow for a natural implementation of async / await over Harp, as described in #70, as well as function calls where the output type is different from the input type.
In both of these cases, the call would be done by sending arguments to a write-only register, and the return would be sent through an event-only register (at some later point, triggered by the call). UIDs to allow matching can be included in the call arguments.
Detailed Design
Below we discuss all the changes required to implement this specification.
device.yml Interface
- Add two new register types:
WriteOnlyandEventOnlyspecifically to be used in the device schema - The firmware level generator should be updated according to the changes below.
Firmware Level Implementation
Add functions in each core to allow configuring a register as either WriteOnly or EventOnly (or simply remove read support). This implies:
- If a register does not support read, it should not be included in the initial state dump
- If a register does not support read, it should report an error on a
Readcommand
Note
WriteOnly and EventOnly cannot be combined with any other type and must stand alone, e.g. [Write, WriteOnly] or [Event, WriteOnly] would be invalid.
Drawbacks
We should be careful that this does not block potentially relevant combinations of register types, and especially revisit how these are specified in the device.yml.
Alternatives
The alternatives below are available for the interface specification part. The biggest disadvantage of both of them is requiring breaking changes to the device.yml schema which could potentially invalidate existing schemas (or perhaps not, to be seen).
Explicit Read in register type lists
An alternative design for the device.yml would be to force the Read type to be explicit. This would not require introducing any new register types, as in the YML you would see [Read, Write] for read/write registers and [Write] for read-only registers. The disadvantage here is needing to update every device.yml ever made.
Make register type an enum in the device.yml
Another alternative design would be to make the register type an explicit enum listing all possibly valid combinations, e.g.:
ReadReadWriteReadEventReadWriteEventWriteWriteEventEvent
If we are careful about this alternative, it might be possible to add the new enum values without breaking the existing schema.
Impact of not ratifying this proposal
Not doing this is blocking a clean design for #70.
Unresolved Questions
- How exactly to represent these two types in the
device.yml? - How exactly to specify these two types in the different core architectures?