Skip to content
Merged
Changes from all commits
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
65 changes: 60 additions & 5 deletions doc/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,12 @@ All common system call operations should have asynchronous versions.

These asynchronous APIs must not use or include any internal/global state.

| Characteristic | Value |
|------------------|-------------------------------|
| Location | `libtock/[category]` |
| Source File Name | `libtock/[category]/[name].c` |
| Header File Name | `libtock/[category]/[name].h` |
| Characteristic | Value |
|-----------------------------------|-------------------------------------|
| Location | `libtock/[category]` |
| Source File Name | `libtock/[category]/[name].c` |
| Header File Name | `libtock/[category]/[name].h` |
| Types Header File Name (Optional) | `libtock/[category]/[name]_types.h` |

### Header Files

Expand Down Expand Up @@ -275,6 +276,13 @@ returncode_t libtock_sensor_read(libtock_sensor_callback_reading cb) {
}
```

### Types Header

If there are any additional types, beyond the callback signature, that are
exposed in the public API of the driver they must be included in the
`libtock/[category]/[name]_types.h` file. This makes it possible to include
these types from `libtock-sync` implementations.

## Synchronous APIs

Most system call interfaces will want to provide a synchronous API as well. This
Expand Down Expand Up @@ -410,3 +418,50 @@ returncode_t libtocksync_sensor_read(int* val) {
return err;
}
```

### More Complicated Example:

Drivers that use allow buffers must un-allow the buffers after the operation
finishes. To ease authoring of cleanup code, Tock provides a macro-based
implementation of the `defer {}` feature that will be included with a future
version of `C`.

```c
#include <libtock/defer.h>

#include "digest.h"
#include "syscalls/digest_syscalls.h"

returncode_t libtocksync_digest_compute(uint8_t* input_buffer,
uint32_t input_buffer_len,
uint8_t* output_buffer,
uint32_t output_buffer_len) {
returncode_t ret;

// First allow for input. If it fails, return.
ret = libtock_digest_set_readonly_allow(input_buffer, input_buffer_len);
if (ret != RETURNCODE_SUCCESS) return ret;
// Now that this buffer has been allowed, set up a `defer` block to
// ensure that it will be unallowed before this function returns
// (regardless of exit location out of the function).
//
// Note the return value of this "un-allow" operation is ignored in favor
// of returning the disposition of the library function (i.e., `ret`).
defer { libtock_digest_set_readonly_allow(NULL, 0); }

// Second allow for output.
ret = libtock_digest_set_readwrite_allow(output_buffer, output_buffer_len);
if (ret != RETURNCODE_SUCCESS) return ret;
// Set up the output unallow.
defer { libtock_digest_set_readwrite_allow(NULL, 0); }

// Attempt the command. If it fails, unallow both buffers.
ret = libtock_digest_command_compute_digest();
if (err != RETURNCODE_SUCCESS) return ret;

// Wait for the digest to compute.
ret = libtock_digest_yield_wait_for(val);

return ret;
}
```