Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 1 | ############################ |
| 2 | The TF-M eRPC Test Framework |
| 3 | ############################ |
| 4 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 5 | The TF-M eRPC Test Framework is a Remote Procedure Call (RPC) based test |
| 6 | framework written in order to have complex test cases running on a host system |
| 7 | which trigger the PSA client APIs on a connected target. |
| 8 | It is based on the `eRPC <https://github.com/EmbeddedRPC/erpc>`__ |
| 9 | project. It is an additional framework to the existing one which runs NS test |
| 10 | suites entirely on the target. It enables you to run test codes on host |
| 11 | machines as if they were running on the device. It has the following advantages: |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 12 | |
| 13 | - Off-load test codes from device to host |
| 14 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 15 | Arm Cortex-M based platform devices usually have limited flash storage which |
| 16 | can only fit small test suites. With test codes running on hosts you can |
| 17 | run far more tests than on the devices, within a richer test environment. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 18 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 19 | - Less frequent image downloading for test code development |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 20 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 21 | As the test codes run on the host, you don't need to update the image on |
| 22 | device when you update test codes. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 23 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 24 | - Host can get test pass or failure directly from the return codes |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 25 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 26 | This would be helpful for test automation because the system which triggers |
| 27 | the tests can read the results programmatically and not relying on parsing |
| 28 | the UART logs like it happens for the current device-based tests. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 29 | |
| 30 | **************** |
| 31 | How Does It Work |
| 32 | **************** |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 33 | Usually, the NS tests are executed in the NSPE of the device. The NS image |
| 34 | on the device contains the test code, which calls into TF-M through the PSA |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 35 | client APIs. |
| 36 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 37 | Using the eRPC test framework, the tests use a client-server architecture: |
| 38 | the NS test code is executed on the host machine as a client, while the NSPE on |
| 39 | the device implements the server side. The NSPE of device side does not run the |
| 40 | test code anymore. When the tests call the PSA client APIs, they call into the |
| 41 | eRPC framework. The eRPC framework handles the communication with the NSPE on |
| 42 | the device, which calls into TF-M through the PSA client APIs. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 43 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 44 | The prototypes of the PSA client APIs are the same while the implementations |
| 45 | are different. Refer to the following sections for more details. |
| 46 | |
| 47 | The Structure |
| 48 | ============= |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 49 | |
| 50 | The following diagram shows the software structure. |
| 51 | |
| 52 | .. figure:: media/erpc_test_framework.svg |
| 53 | |
| 54 | - eRPC Framework |
| 55 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 56 | The eRPC (Embedded Remote Procedure Call) framework system. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 57 | |
| 58 | - eRPC Client Shim |
| 59 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 60 | The eRPC generated shim layer of remote APIs for clients. It serializes the |
| 61 | identifier of the API and its parameters into a stream of bytes and |
| 62 | transports to the server through a communication channel such as |
| 63 | UART and TCP/IP. The codes are generated by the `erpcgen tool <https://github.com/EmbeddedRPC/erpc/wiki/erpcgen>`_. |
| 64 | To re-generate the shim code for server and client side: |
| 65 | |
| 66 | .. code-block:: bash |
| 67 | |
| 68 | cd <tf-m-tests/erpc> |
| 69 | erpcgen -o generated_files/ -v tfm.erpc |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 70 | |
| 71 | - eRPC Server Shim |
| 72 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 73 | The generated shim layer of the server. It registers a callback function to |
| 74 | the eRPC framework. When the framework receives any requests from the client, |
| 75 | it calls the callback function. The callback deserializes the byte stream |
| 76 | to determine what API to call and then invokes it with the corresponding |
| 77 | parameters from the byte stream. And then it returns the results to the |
| 78 | client in the reverse routine. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 79 | |
| 80 | - API Wrapper |
| 81 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 82 | Part of the parameters of ``psa_call`` API is not supported by eRPC directly, |
| 83 | thus an API wrapper is required to transform the ``in_vec/out_vec`` |
| 84 | structures to eRPC supported data types. The wrapper API is named as |
| 85 | ``erpc_psa_call``. On the client side, the wrapper implements the |
| 86 | ``psa_call`` which calls the ``erpc_psa_call`` in the client shim layer. |
| 87 | On the server side, the wrapper implements the ``erpc_psa_call`` which is |
| 88 | called by the shim layer. The ``erpc_psa_call`` then calls the ``psa_call``. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 89 | |
| 90 | - Test Suites |
| 91 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 92 | It can be the existing TF-M regression tests or any other tests that interact |
| 93 | with TF-M using the PSA Client APIs. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 94 | |
| 95 | - Host App |
| 96 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 97 | Initializes the eRPC client and starts the test suites. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 98 | |
| 99 | - Target App |
| 100 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 101 | Initializes the eRPC server and listens for requests from the eRPC client. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 102 | |
| 103 | Supported APIs |
| 104 | ============== |
| 105 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 106 | The APIs supported for doing RPC are the PSA Client APIs because they are the |
| 107 | lowest level APIs that interact with TF-M. You can build lots of test suites |
| 108 | upon them. You can also add your own APIs in the ``tfm.erpc`` file. |
| 109 | Please refer to `IDL Reference <https://github.com/EmbeddedRPC/erpc/wiki/IDL-Reference>`_ |
| 110 | for the syntax of the file. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 111 | |
| 112 | API Grouping |
| 113 | ************ |
| 114 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 115 | PSA Client APIs are categorized into common APIs and connection-based service |
| 116 | APIs. Connection-based APIs can only be used if there are connection-based |
| 117 | services enabled in TF-M, otherwise they return with an error code. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 118 | |
| 119 | Common APIs: |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 120 | - psa_framework_version() |
| 121 | - psa_version() |
| 122 | - psa_call() |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 123 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 124 | Connection-based specific APIs: |
| 125 | - psa_connect() |
| 126 | - psa_close() |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 127 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 128 | Transportation layer |
| 129 | ==================== |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 130 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 131 | On the device side, only UART transportation is supported in NSPE being the |
| 132 | most common peripheral that is generally available on all supported platforms. |
| 133 | For the host side, both UART and TCP are available. The main use case of the |
| 134 | TCP transport from the host side is to interface with Fast Models (FVPs) where |
| 135 | the UART data is getting transferred between a TCP/IP socket of the host and a |
| 136 | serial port of the target. This happens with the help of a virtual component |
| 137 | of the model called the TelnetTerminal which acts as a gateway between the host |
| 138 | and the target. See the `Fast Models reference guide |
| 139 | <https://developer.arm.com/documentation/100966/1116/Getting-Started-with-Fixed-Virtual-Platforms/Using-a-terminal-with-a-system-model>`_ |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 140 | for more details. |
| 141 | |
| 142 | ******************** |
| 143 | Platform Integration |
| 144 | ******************** |
| 145 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 146 | As a basic requirement the platform must provide a UART driver that is |
| 147 | compliant with the `CMSIS-Driver specification |
| 148 | <https://www.keil.com/pack/doc/CMSIS_Dev/Driver/html/index.html>`_ and support |
| 149 | the enablement of the receiver and transmitter side of the peripheral via the |
| 150 | ``ARM_USART_Control()`` CMSIS API. These requirements are coming from the fact |
| 151 | that the UART transport implementation `in eRPC |
| 152 | <https://github.com/EmbeddedRPC/erpc/blob/1.9.1/erpc_c/transports/erpc_uart_cmsis_transport.h>`_ |
| 153 | is based on CMSIS-Driver APIs. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 154 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 155 | Secondly, platforms need to create their folders under the ``erpc/platform`` |
| 156 | and then create the ``config_erpc_target.h`` to specify the UART port to be |
| 157 | used for eRPC transportation. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 158 | |
| 159 | .. code-block:: |
| 160 | |
| 161 | #define ERPC_UART Driver_USART0 |
| 162 | |
Kevin Peng | 0512262 | 2023-07-21 11:32:15 +0800 | [diff] [blame] | 163 | .. note:: |
| 164 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 165 | The folder structure in ``erpc/platform`` must be the same as the |
| 166 | ``platform/ext/target`` of the TF-M repository. |
Kevin Peng | 0512262 | 2023-07-21 11:32:15 +0800 | [diff] [blame] | 167 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 168 | It is recommended to use a different UART than the one used for stdio. If the |
| 169 | same UART device is used for both, then the TF-M logs (both SPM and |
| 170 | Secure Partitions) and any log messages from the NSPE must be disabled. |
| 171 | Otherwise, the eRPC transportation might fail. This happens when the eRPC |
| 172 | messages are intermixed with other data (e.g. log messages) on the same UART |
| 173 | device ultimately corrupting eRPC communication. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 174 | |
| 175 | *********************** |
| 176 | Application Integration |
| 177 | *********************** |
| 178 | |
| 179 | The TF-M eRPC test framework provides two CMake libraries for integration. |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 180 | One is the ``erpc_client``, the other is the ``erpc_server``. Both include the |
| 181 | eRPC framework, the shim layers, API wrappers and expose an initialization API |
| 182 | for the client and server respectively. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 183 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 184 | The initialization does not include the initialization of the transportation |
| 185 | layer as it is use case specific which kind of transportation is used. It is |
| 186 | the responsibility of the client and server applications to initialize the |
| 187 | transportation layers and pass them to the ``erpc_client`` and ``erpc_server`` |
| 188 | components. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 189 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 190 | TF-M provides the ``app/erpc_app.c`` as the default server application which |
| 191 | first initializes a CMSIS UART transport and then starts the eRPC server. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 192 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 193 | The ``CONFIG_TFM_ERPC_TEST_FRAMEWORK`` configuration option is provided to |
| 194 | enable the eRPC framework on the device (server) side. The default server |
| 195 | application will be automatically built and developers will only need to focus |
| 196 | on the client application development. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 197 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 198 | In summary, on the server side the only requirement is to enable |
| 199 | ``CONFIG_TFM_ERPC_TEST_FRAMEWORK`` option at build time. On the client side, |
| 200 | one must: |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 201 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 202 | - Initialize the transportation layer using eRPC provided APIs, |
| 203 | - Call the eRPC client initialization function provided by TF-M's eRPC test |
| 204 | framework with the transportation instance initialized above |
| 205 | as its parameter, |
| 206 | - Develop the application code, |
| 207 | - Building with CMake: |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 208 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 209 | - ``add_subdirectory`` with the ``erpc/client``, |
| 210 | - link the ``erpc_client`` library to the application. |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 211 | |
David Vincze | aa40361 | 2024-12-02 10:00:09 +0000 | [diff] [blame] | 212 | For more information on how to build and run the TF-M regression test suites |
| 213 | on various platforms please refer to :doc:`this document <tfm_erpc_test_build_and_run>`. |
| 214 | There is also an example of a simple host application at |
| 215 | ``erpc/host_example`` for reference. |
| 216 | |
| 217 | .. toctree:: |
| 218 | :caption: Examples |
| 219 | :titlesonly: |
| 220 | :hidden: |
| 221 | |
| 222 | eRPC Test Build and Run <tfm_erpc_test_build_and_run> |
Kevin Peng | ee2c3a9 | 2022-12-20 12:12:59 +0800 | [diff] [blame] | 223 | |
| 224 | -------------- |
| 225 | |
David Vincze | 01c9a04 | 2024-10-31 12:54:44 +0000 | [diff] [blame] | 226 | *Copyright (c) 2023-2024, Arm Limited. All rights reserved.* |