[][src]Trait kernel::Driver

pub trait Driver {
    fn subscribe(
        minor_num: usize,
        callback: Option<Callback>,
        app_id: AppId
    ) -> ReturnCode { ... }
fn command(
        minor_num: usize,
        r2: usize,
        r3: usize,
        caller_id: AppId
    ) -> ReturnCode { ... }
fn allow(
        app: AppId,
        minor_num: usize,
        slice: Option<AppSlice<Shared, u8>>
    ) -> ReturnCode { ... } }

Drivers implement the three driver-specific system calls: subscribe, command and allow.

See the module level documentation for an overview of how system calls are assigned to drivers.

Provided Methods

subscribe lets an application pass a callback to the driver to be called later. This returns ENOSUPPORT if not used.

Calls to subscribe should do minimal synchronous work. Instead, they should defer most work and returns results to the application via the callback. For example, a subscribe call might setup a DMA transfer to read from a sensor, and asynchronously respond to the application by passing the result to the application via the callback.

Drivers should allow each application to register a single callback for each minor number subscription. Thus, a second call to subscribe from the same application would replace a previous callback.

This pushes most per-application virtualization to the application itself. For example, a timer driver exposes only one timer to each application, and the application is responsible for virtualizing that timer if it needs to.

The driver should signal success or failure through the sign of the return value from subscribe. A negative return value signifies an error, while positive a return values signifies success. In addition, the magnitude of the return value of can signify extra information such as error type.

command instructs a driver to perform some action synchronously. This returns ENOSUPPORT if not used.

The return value should reflect the result of an action. For example, enabling/disabling a peripheral should return a success or error code. Reading the current system time should return the time as an integer.

Commands should not execute long running tasks synchronously. However, commands might "kick-off" asynchronous tasks in coordination with a subscribe call.

All drivers must support the command with minor_num 0, and return 0 or greater if the driver is supported. This command should not have any side effects. This convention ensures that applications can query the kernel for supported drivers on a given platform.

allow lets an application give the driver access to a buffer in the application's memory. This returns ENOSUPPORT if not used.

The buffer is shared between the application and driver, meaning the driver should not rely on the contents of the buffer to remain unchanged.


impl Driver for IPC

subscribe enables processes using IPC to register callbacks that fire when notify() is called.

command is how notify() is implemented. Notifying an IPC service is done by setting client_or_svc to 0, and notifying an IPC client is done by setting client_or_svc to 1. In either case, the target_id is the same number as provided in a notify callback or as returned by allow.

Returns EINVAL if the other process doesn't exist.

allow enables processes to discover IPC services on the platform or share buffers with existing services.

If allow is called with target_id == 0, it is an IPC service discover call. The contents of the slice should be the string name of the IPC service. If this mechanism can find that service, allow will return an ID that can be used to notify that service. Otherwise an error will be returned.

If allow is called with target_id >= 1, it is a share command where the application is explicitly sharing a slice with an IPC service (as specified by the target_id). allow() simply allows both processes to access the buffer, it does not signal the service.