Skip to content

FileHandle: Mbed OS 5.12 updates #992

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

Merged
merged 4 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion docs/api/platform/FileHandle.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Blocking I/O | Yes (always) | Yes (default)
Nonblocking I/O | No | Yes | Yes
Poll | No | Yes (struct pollfd) | Yes (struct pollfh)
Sigio | No | No | Yes
Disable input or output | No | No | Yes
Device-specific extensions | No | No | Possible using derived types
Newline conversion | Yes (enabled with JSON) | No | No
Error indications | EOF, ferror, set errno | Return -1, set errno | Return negative error code
Expand All @@ -51,9 +52,13 @@ Calls are provided to attach already-opened lower levels to the higher levels:
- `FILE *fdopen(int fd, const char *mode)` bind a POSIX file descriptor to a stdio FILE.
- `FILE *fdopen(FileHandle *fh, const char *mode)` bind a FileHandle to a stdio FILE.

The only call provided to map from higher level to lower-level is:

- `FileHandle *mbed_file_handle(int fd)` obtain the FileHandle for a POSIX file descriptor

The standard POSIX function `int fileno(FILE *stream)` may be available to map from `FILE` to file descriptor, depending on the toolchain and C library in use - it is not usable in fully portable Mbed OS code.

As it is not possible to map from higher levels to lower levels, if code needs to access the lower levels, use a lower-level open call, so the lower-level handle is known. Then, bind that to the higher level..
As it is not possible to map from `FILE` to lower levels, if code needs to access the lower levels, rather than use `fopen`, use a lower-level open call then `fdopen` to create the `FILE`.

The POSIX file descriptors for the console are available as `STDIN_FILENO`, `STDOUT_FILENO` and `STDERR_FILENO`, permitting operations such as `fsync(STDERR_FILENO)`, which would for example drain `UARTSerial`s output buffer.

Expand Down Expand Up @@ -112,6 +117,14 @@ Important notes on sigio:

Ordinary files do not generate sigio callbacks because they are always readable and writable.

#### Suspending a device

Having a device open via a `FileHandle` may cost power, especially if open for input. For example, for `UARTSerial` to be able to receive data, the system must not enter deep sleep, so deep sleep will be prevented while the `UARTSerial` is active.

To permit power saving, the device can be closed or destroyed, or you can indicate that you do not currently require input or output by calling `FileHandle::enable_input` or `FileHandle::enable_output`. Disabling input or output effectively suspends the device in that direction, which can permit power saving.

This is particularly useful when an application does not require console input - it can indicate this by calling `mbed_file_handle(STDIN_FILENO)->enable_input(false)` once at the start of the program. This will permit deep sleep when `platform.stdio-buffered-serial` is set to true.

#### Stream-derived FileHandles

`Stream` is a legacy class that provides an abstract interface for streams similar to the `FileHandle` class. The difference is that the `Stream` API is built around the `getc` and `putc` set of functions, whereas `FileHandle` is built around `read` and `write`. This makes implementations simpler but limits what is possible with the API. Because of this, implementing the `FileHandle` API directly is suggested API for new device drivers.
Expand Down Expand Up @@ -214,3 +227,4 @@ int main()
- [File](file.html).
- [FileSystem](filesystem.html).
- [Poll](poll.html).
- [Power management](powermanagement.html).
10 changes: 9 additions & 1 deletion docs/api/platform/PowerManagement.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,15 @@ These Mbed OS drivers can lock the deep sleep:
- `SPI`.
- `I2C`.
- `CAN`.
- `SerialBase`.
- `SerialBase` (and hence `Serial` and `UARTSerial`)

#### Console versus deep sleep

By default, on entry to `main`, the deep sleep lock will not be held, so deep sleep will be possible until a driver or other code locks it.

However, if `platform.stdio-buffered-serial` is set to true, then `UARTSerial` installs an interrupt handler to receive serial data for `stdin`. This will block deep sleep. To permit deep sleep, input must be suspended (permanently or temporarily). Making the call `mbed_file_handle(STDIN_FILENO)->enable_input(false)` from the application gives the console driver, whatever it is, permission to stop reception. If `UARTSerial` is providing `stdin`, this removes the receive interrupt handler and releases the deep sleep lock.

For more information see [`FileHandle`](filehandle.html).

#### Sleep/Deep sleep profiling tool

Expand Down