| # Interact with the driver |
| |
| Software on Fuchsia interacts with driver components through their exposed |
| service capabilities. Once a client connects to the driver's service, it |
| receives an instance of the FIDL protocol representing that driver. For more |
| details, see the [Driver Communication][driver-communication] guide. |
| |
| In this section, you'll create a new `eductl` executable that discovers and |
| interacts with the capabilities exposed by the `qemu_edu` driver. |
| |
| ## Create a new tools component |
| |
| Create a new project directory in your Bazel workspace for a new binary tool: |
| |
| ```posix-terminal |
| mkdir -p fuchsia-codelab/qemu_edu/tools |
| ``` |
| |
| After you complete this section, the project should have the following directory |
| structure: |
| |
| ```none {:.devsite-disable-click-to-copy} |
| //fuchsia-codelab/qemu_edu/tools |
| |- BUILD.bazel |
| |- eductl.cc |
| ``` |
| |
| Create the `qemu_edu/tools/BUILD.bazel` file and add the following statement to |
| include the necessary build rules from the Fuchsia SDK: |
| |
| `qemu_edu/tools/BUILD.bazel`: |
| |
| ```bazel |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/BUILD.bazel" region_tag="imports" adjust_indentation="auto" %} |
| ``` |
| |
| Create a new `qemu_edu/tools/eductl.cc` file with the following code to set up a |
| basic command line executable: |
| |
| `qemu_edu/tools/eductl.cc`: |
| |
| ```cpp |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="imports" adjust_indentation="auto" %} |
| |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="cli_helpers" adjust_indentation="auto" %} |
| |
| int main(int argc, char* argv[]) { |
| const char* cmd = basename(argv[0]); |
| |
| // ... |
| |
| return usage(cmd); |
| } |
| |
| ``` |
| |
| This executable supports two subcommands to execute the liveness check and |
| factorial computation. |
| |
| Add the following new rules to the bottom of the project's build configuration |
| to build this new tool into a Fuchsia package: |
| |
| `qemu_edu/tools/BUILD.bazel`: |
| |
| ```bazel |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/BUILD.bazel" region_tag="binary" adjust_indentation="auto" exclude_regexp="\/\/src\/qemu_edu" %} |
| |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/BUILD.bazel" region_tag="component" adjust_indentation="auto" %} |
| |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/BUILD.bazel" region_tag="package" adjust_indentation="auto" %} |
| ``` |
| |
| ## Implement the client tool |
| |
| Clients connect to the driver's exposed service to receive an instance of the |
| FIDL protocol. Add the following code to `eductl` to connect to the `edu` |
| device service: |
| |
| `qemu_edu/tools/eductl.cc`: |
| |
| ```cpp |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="imports" adjust_indentation="auto" %} |
| |
| {{ '<strong>' }}{% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="fidl_imports" adjust_indentation="auto" %}{{ '</strong>' }} |
| |
| {{ '<strong>' }}{% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="service_client" adjust_indentation="auto" %}{{ '</strong>' }} |
| |
| // ... |
| ``` |
| |
| Add `liveness_check()` and `compute_factorial()` functions to call methods using |
| the `examples.qemuedu/Device` FIDL protocol returned from `ConnectToDevice()`. |
| Finally, update the tool's `main()` function to call the appropriate device |
| function based on the argument passed on the command line: |
| |
| `qemu_edu/tools/eductl.cc`: |
| |
| ```cpp |
| // ... |
| |
| {{ '<strong>' }}{% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="liveness_check" adjust_indentation="auto" %}{{ '</strong>' }} |
| |
| {{ '<strong>' }}{% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="compute_factorial" adjust_indentation="auto" %}{{ '</strong>' }} |
| |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/eductl.cc" region_tag="main" adjust_indentation="auto" highlight="4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20" %} |
| ``` |
| |
| Update the tool's build configuration to depend on the FIDL bindings for the |
| `examples.qemuedu` library: |
| |
| `qemu_edu/tools/BUILD.bazel`: |
| |
| {% set build_bazel_snippet %} |
| {% includecode gerrit_repo="fuchsia/sdk-samples/drivers" gerrit_path="src/qemu_edu/tools/BUILD.bazel" region_tag="binary" adjust_indentation="auto" highlight="7" %} |
| {% endset %} |
| |
| ```bazel |
| {{ build_bazel_snippet|replace("//src/qemu_edu","//fuchsia-codelab/qemu_edu")|trim() }} |
| ``` |
| |
| <<_common/_restart_femu.md>> |
| |
| ## Reload the driver |
| |
| Use the `bazel run` command to build and execute the driver component target: |
| |
| ```posix-terminal |
| bazel run //fuchsia-codelab/qemu_edu/drivers:pkg.component |
| ``` |
| |
| ## Run the tool |
| |
| Use the `bazel run` command to build and execute the tool, passing the arguments |
| `fact 12` to compute the factorial of 12: |
| |
| ```posix-terminal |
| bazel run //fuchsia-codelab/qemu_edu/tools:pkg.eductl_tool -- fact 12 |
| ``` |
| |
| The `bazel run` command performs the following steps: |
| |
| 1. Build the executable and package. |
| 1. Publish the package to a local package repository. |
| 1. Register the package repository with the target device. |
| 1. Use `ffx driver run-tool` to run the binary inside the `driver_playground` |
| component. |
| |
| The command prints output similar to the following with the computation result |
| the factorial: |
| |
| ```none {:.devsite-disable-click-to-copy} |
| Factorial(12) = 479001600 |
| ``` |
| |
| Congratulations! You've successfully connected to your driver's exposed services |
| from a separate client. |
| |
| <!-- Reference links --> |
| |
| [driver-communication]: /docs/concepts/drivers/driver_communication.md |