HIL design TRD

32 views
Skip to first unread message

Philip Levis

unread,
Apr 15, 2021, 6:16:01 PM4/15/21
to Tock Embedded OS Development Discussion
While writing the HIL design TRD, I went through Tock’s APIs for examples. I realized that many of our current APIs don’t follow all of the rules. This is mostly for historical reasons: some of the HILs/APIs were written a long time ago, before we understood the issues as well as we do now.

I’m planning on going through some of the core HILs and updating them to follow the TRD, or if/where they don’t explaining why. In some cases this will involve updating the system call API for a given device. For example, currently the ADC device doesn’t propagate errors on data sampling.

My rough planned order:
  - adc
  - crc
  - digest 
  - entropy
  - rng
  - symmetric_encryption

I hope to write a TRD for each HIL (or Entropy/Random together) as I cover it. If anyone would like to help (with code, TRDs, or both), let me know!

Phil

———————
Philip Levis (he/him)
Associate Professor, Computer Science and Electrical Engineering
Faculty Director, lab64 Maker Space
Stanford University
http://csl.stanford.edu/~pal

Hudson Randal Ayers

unread,
Apr 17, 2021, 2:52:46 PM4/17/21
to Philip Levis, Tock Embedded OS Development Discussion
I think https://github.com/tock/tock/pull/2538 introduces one aspect of HIL design not covered by the HIL design TRD: how to handle errors in HILs where we have custom error types. I2C defines a custom error type that allows for returning expressive, I2C specific errors to callers. But the HIL design TRD recommends always returning `ErrorCode` in HIL.

There are probably some tricky tradeoffs here: more expressive errors improve code readability and probably allow for better error handling in cases where the existing set of `ErrorCode` options are insufficient to represent all the different errors that might happen. But having lots of custom error types in the Tock kernel would probably increase code size, and handling errors succinctly becomes hard when there are functions with lots of different error types (e.g. if you enter a grant, call one function that returns a Result<(), ErrorCode>, then call another function that returns a Result<(), I2CError>, there is potential for a lot of boilerplate code to convert the different error types and return them to userspace).

I am not sure the best solution here but think it is probably something we should consider as part of converting outdated HILs.

Hudson
Pull Request Overview This pull request modifies the I2C HIL so that request functions return the given buffer upon error. Without this, the i2c caller will loose the buffers if the I2C device is b...



From: tock...@googlegroups.com <tock...@googlegroups.com> on behalf of Philip Levis <p...@cs.stanford.edu>
Sent: Thursday, April 15, 2021 3:14 PM
To: Tock Embedded OS Development Discussion <tock...@googlegroups.com>
Subject: [tock-dev] HIL design TRD
 
--
You received this message because you are subscribed to the Google Groups "Tock Embedded OS Development Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tock-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/tock-dev/B1B1B2BA-42C4-41C2-8879-D88B2AB9ACF8%40cs.stanford.edu.

Alexandru Radovici

unread,
Apr 17, 2021, 3:07:35 PM4/17/21
to Hudson Randal Ayers, Philip Levis, Tock Embedded OS Development Discussion
I still think the HIL should return only ErrorCode. In this example for instance, if the HIL functions return I2CError, it may happen that a function can return I2CError::CommandComplete. This takes us back to the ReturnCode issue, where SUCCESS and Error were defined in the same type.

Another issue in HIL TRD seems to be virtualization. If a HIL is used in a virtualized driver, the "commands" usually do not return synchronous errors, as they have to wait for their turn with the actual driver. The only way they can return error is via a callback. The problem is that not all HILs define errors in callback. An example is the SpiMasterClient, that does not provide an Error.

Alexandru



--
Alexandru RADOVICI
Universitatea "Politehnica" din Bucuresti

e-mail: al...@ipworkshop.ro
telefon: 0742061223
www.ipworkshop.ro

Philip Levis

unread,
Apr 18, 2021, 1:00:23 AM4/18/21
to Hudson Randal Ayers, Tock Embedded OS Development Discussion
I think that Rule 2 actually addresses this:

"Generally speaking, every HIL operation should return a Rust Result type, whose Err variant includes an error code. The Tock kernel provides a standard set of error codes, oriented towards system calls, in the kernel::ErrorCode enum. Sometimes, however, these error codes don't quite fit the use case and so a HIL defines its own error codes. The I2C HIL, for example, defines an i2c::Error enumeration for cases such as address and data negative acknowledgments, which can occur in I2C.”

I think this means that Rule 6 should be rewritten to generalize from `Result<(), ErrorCode>` to just a Result, noting that the Err should be able to pass a superset of the errors returned synchronously?

Phil


Philip Levis

unread,
Apr 18, 2021, 1:02:35 AM4/18/21
to Alexandru Radovici, Hudson Randal Ayers, Tock Embedded OS Development Discussion

On Apr 17, 2021, at 12:07 PM, Alexandru Radovici <msg4...@gmail.com> wrote:

I still think the HIL should return only ErrorCode. In this example for instance, if the HIL functions return I2CError, it may happen that a function can return I2CError::CommandComplete. This takes us back to the ReturnCode issue, where SUCCESS and Error were defined in the same type.

I think I’ll push back on this and say that ErrorCode is preferred but it’s OK to return other errors if you need to. A capsule can map these other errors into ErrorCode for userspace.


Another issue in HIL TRD seems to be virtualization. If a HIL is used in a virtualized driver, the "commands" usually do not return synchronous errors, as they have to wait for their turn with the actual driver. The only way they can return error is via a callback. The problem is that not all HILs define errors in callback. An example is the SpiMasterClient, that does not provide an Error.

Yes, that’s Rule 6. We need to clean up a bunch of the HILs and bring them in line with this TRD.

Phil




Hudson Randal Ayers

unread,
Apr 18, 2021, 10:06:41 PM4/18/21
to Philip Levis, Alexandru Radovici, Tock Embedded OS Development Discussion
I think the missing element from the TRD is how custom error types should be exposed when they are needed. Should we require that the HIL functions and the error-reporting callback communicate errors via the same type? Or is a mismatch acceptable (as in https://github.com/tock/tock/pull/2538)

Hudson
Pull Request Overview This pull request modifies the I2C HIL so that request functions return the given buffer upon error. Without this, the i2c caller will loose the buffers if the I2C device is b...


Sent: Saturday, April 17, 2021 10:02 PM
To: Alexandru Radovici <msg4...@gmail.com>
Cc: Hudson Randal Ayers <hay...@stanford.edu>; Tock Embedded OS Development Discussion <tock...@googlegroups.com>
Subject: Re: [tock-dev] HIL design TRD
 

Philip Levis

unread,
Apr 19, 2021, 1:50:11 AM4/19/21
to Hudson Randal Ayers, Alexandru Radovici, Tock Embedded OS Development Discussion
While I think we should encourage them to have the same error type, I think a mismatch has to be acceptable. The issue is that the callback errors are a superset. In the best/standard case, you include callback-only errors in the type and just don’t return them synchronously. But if these is a situation where that *really* doesn’t make sense (I can’t think of one, but it could exist…), it can be OK to return different types. This does require separate mappings (e.g., to ErrorCode). My first guess is that the TRD should say something like “The error type returned in a callback SHOULD be the same error type returned synchronously.” And then explain why.

Phil
Reply all
Reply to author
Forward
0 new messages