A Remote Procedure Call (RPC) allows a computer program calling a procedure to execute in another remote processor, while hiding the details of the remote interaction. FastRPC is the RPC mechanism used to enable remote function calls between the CPU and DSP.
Customers with algorithms that benefit from being executed on the DSP can use the FastRPC framework to offload large processing tasks onto the DSP. The DSP can then leverage its internal processing resources, such as HVX, to execute the tasks in a more compute- and power-efficient way than the CPU.
FastRPC interfaces are defined in an IDL file, and they are compiled using the QAIC compiler to generate header files and stub and skel code. The header files and stub should be built and linked into the CPU executable while the header files and skel should be built and linked into the DSP library.
The following diagram depicts the major FastRPC software components on the CPU and DSP.
Stub and skel are generated by the IDL compiler. Other modules are part of the software stack on the device.
Definition of the terms in the diagram:
The FastRPC framework consists of the following components.
Workflow:
- The CPU process calls the stub version of the function. The stub code converts the function call to an RPC message.
- The stub code internally invokes the FastRPC framework on the CPU to queue the converted message.
- The FastRPC framework on the CPU sends the queued message to the FastRPC DSP framework on the DSP.
- The FastRPC DSP framework on the DSP dispatches the call to the relevant skeleton code.
- The skeleton code un-marshals the parameters and calls the method implementation.
- The skeleton code waits for the implementation to finish processing, and, in turn, marshals the return value and any other output arguments into the return message.
- The skeleton code calls the FastRPC DSP framework to queue the return message to be transmitted to the CPU.
- The FastRPC DSP framework on the DSP sends the return message back to the FastRPC framework on the CPU.
- The FastRPC framework identifies the waiting stub code and dispatches the return value.
- The stub code un-marshals the return message and sends it to the calling User mode process.
Hexagon SDK documentation covers all the required details about FastRPC. Please download and install the Hexagon SDK from the following location: Hexagon SDK
git clone https://github.com/quic/fastrpc
cd fastrpc
./gitcompile
sudo make install
-
Install Linaro tools and add the tools bin location to the path:
wget -c https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-i686_aarch64-linux-gnu.tar.xz tar xf gcc-linaro-7.5.0-2019.12-i686_aarch64-linux-gnu.tar.xz export PATH="$PATH:<linaro tools path>/toolchain/bin"
-
Create softlink files for the compiler, linker, and other tools. Create environment variables as below for the auto tools:
export CC=aarch64-linux-gnu-gcc export CXX=aarch64-linux-gnu-g++ export AS=aarch64-linux-gnu-as export LD=aarch64-linux-gnu-ld export RANLIB=aarch64-linux-gnu-ranlib export STRIP=aarch64-linux-gnu-strip
-
Sync and compile using the below command:
git clone https://github.com/quic/fastrpc cd fastrpc ./gitcompile --host=aarch64-linux-gnu
-
Download Android NDK from here, and set up the
ANDROID_NDK_HOME
environment variable as mentioned. Add the tools bin location to the path:export ANDROID_NDK_HOME="/usr/home/android_ndk" export PATH="$PATH:$ANDROID_NDK_HOME/toolchain/bin"
-
Create softlink files for the compiler, linker, and other tools. Create environment variables as below for the auto tools:
export CC=aarch64-linux-android34-clang export CXX=aarch64-linux-android34-clang++ export AS=llvm-as export LD=ld export RANLIB=llvm-ranlib export STRIP=llvm-strip
-
Sync and compile using the below command:
git clone https://github.com/quic/fastrpc cd fastrpc ./gitcompile --host=aarch64-linux-android
For detailed instructions on testing FastRPC, please refer to the README.md in the test
directory.
Both VERIFY and FARF are logging mechanisms used in fastRPC. While VERIFY is a legacy module, FARF is commonly utilized on both DSP (Digital Signal Processor) and HLOS (High-Level Operating System).
VERIFY_IPRINTF(format, ...)
: This macro is enabled byVERIFY_PRINT_INFO
and is used for debug logs.VERIFY_EPRINTF(format, ...)
: Enabled byVERIFY_PRINT_ERROR
, this macro is used for error logs.VERIFY_WPRINTF(format, ...)
: This macro is enabled byVERIFY_PRINT_WARN
and is used for warnings.VERIFY_EPRINTF_ALWAYS(format, ...)
: This macro does not require any enabling macros and is used for logs that should always be printed.
Example:
#include "verify.h"
#define VERIFY_PRINT_ERROR
VERIFY_EPRINTF("Error: Operation failed with result %d\n", result);
The FARF API is a macro used to print debug logs. It allows developers to selectively enable or disable certain types of messages based on their priority level. The priority levels include LOW, MEDIUM, HIGH, ERROR, FATAL, and ALWAYS.
Key Points:
- Usage: FARF is used similarly to the
printf
function, where the first parameter is the level of the message, and the rest are the message contents. - Levels: The FARF levels allow users to control the verbosity of the logs. For example, setting a FARF level to 1 enables the corresponding FARF macros to be compiled in.
- Runtime FARF: Runtime FARF messages are prefixed with "RUNTIME_" and can be enabled or disabled at runtime. These messages are always compiled in but can be controlled during execution.
- Implementation: To use FARF, the header file
HAP_farf.h
needs to be included in the build. This inclusion is typically sufficient to enable FARF.
Example Code:
#define FARF_LOW 1
#include "HAP_farf.h"
FARF(LOW, "LOW message");
FARF(HIGH, "HIGH message"); // This message will not be compiled in
- adsprpcd.farf: This file is used to configure the FARF logging levels. You can specify which levels of logs should be enabled.
- adsprpcd.debugconfig: This file can be used to configure additional debug settings.
Logs from the DSP can be obtained using the logging mechanisms described above. When userspace and kernel logs indicate that an error is received from the DSP, you can use the FARF and VERIFY macros to capture and analyze the logs for troubleshooting.
When reporting bugs, please provide the following details to facilitate debugging:
- Platform/SoC Name: Specify the name of the platform or System on Chip (SoC) being used.
- User Space Library Version/HLOS Build Details: Include the version of the user space library and details of the High-Level Operating System (HLOS) build.
- Kernel Version: Provide the version of the kernel.
- stdout & stderr for User Space: Share the standard output and standard error logs for the user space.
- dmesg Logs: Include the dmesg logs.
- User Library Logs: Can be captured from /var/log/syslog
- QXDM/mini-dm Logs: Provide QXDM or mini-dm logs. Note that the Hexagon SDK includes mini-dm for collecting logs from the DSP.
- Tests Run & Parameters: Detail the tests that were run along with their parameters, including any environment variables explicitly set for FastRPC.
- Custom Test Code: If a custom test was conducted, please share a code snippet or the complete code to reproduce the issue.
- Performance Logs: For performance-related issues, provide performance logs enabled by setting specific environment variables. The following environment variables can be used:
export FASTRPC_PERF_KERNEL=1
export FASTRPC_PERF_ADSP=1
export FASTRPC_PERF_FREQ=1
- ftrace Logs: Include ftrace logs for performance issues.
- Hexagon SDK documentation: Hexagon SDK
- Linaro documentation: Testing FastRPC
Thanks for your interest in contributing to FastRPC! Please read our Contributions Page for more information on contributing features or bug fixes. We look forward to your participation!
FastRPC is licensed under the BSD 3-clause "New" or "Revised" License. Check out the LICENSE for more details.