PC-Gateway
The miniHIL currently uses the USB port together with the winUSB driver and a proprietary multichannel protocol to connect to the miniHIL software running on the PC. To allow easier integration with existing tools/debuggers/APIs we provide two options which allow the test cases and actors to communicate with custom software running on the PC.
Option one is the so called "whitebox test interface". It provides a predefined set of messages which can be used to communicate between the miniHIL and a PC application.
The second option is to use the "multi channel pass through" functionality. This provides an interface to forward blobs of bytes between a miniHIL actor and a tcp socket on the PC. The structure of the passed data is completely free and has to be adapted to the users requirement.
|
A normal PC (with Windows) is not realtime capable. Therefore, no realtime guarantees can be given for the interaction of actors and test cases with the PC. This does not influence the realtime behavior of actors which do not depend on the PC connection (i.e. which are executed on the miniHIL processor). |
|
This documentation page is work in progress. Please contact us if you have any questions. |
The "whitebox test" interface
The whitebox test interface consists of two parts:
-
The miniHIL API
-
The miniHIL whitebox PC application
While the miniHIL API may be used with a custom PC application, that is not recommended. If the debug infrastructure is used the default pc scripts use pyocd to connect to the target. This requires supported DUT binary with debug information (e.g. an elf file) and a cmsis pack to be configured.
Alternatively the default debugger may be disabled in the .ini file. Then only the runCustom function is available.
The "whitebox" miniHIL API
The miniHIL API provides three C-functions which may be used in actor or cage target/action code to send messages to the PC software:
/*
* Instruct the PC application to read a 1, 2 or 4 byte int from the provided symbol name and compare the read value to the passed value.
* Values are read using a pyocd compatible debugger connected to the target
* In case of a match the PC application will send a "done" message with payload == 0.
* In case of a value mismatch the payload will be == 1.
* Negative payloads are returned for other errors.
*/
void Wb_expectInt(const char* name, int64_t value);
/*
* Instruct the PC application to write a 1, 2 or 4 byte int value to the provided symbol name.
* Values are written using a pyocd compatible debugger connected to the target.
* If the value could be written the PC application will send a "done" message with payload == 0.
* Negative payloads are returned for errors.
*/
void Wb_setInt(const char* name, int64_t value);
/*
* Instruct the PC application to call a custom script. The script to call is identified by the passed name.
* The parameter value will be forwarded to the custom script.
* The custom script must return a "done" message. The payload depends on the users script.
*/
void Wb_runCustom(const char* name, const char* parameter);
In addition the miniHIL API provides an actor which decodes PC messages and provides them via a port: whitebox.api.whitebox.AWhiteboxRemote.
Once added to your miniHIL project you can connect the actors whitebox port (Protocol: PWhiteboxRemote) to your test actor or any other custom actor. You can then use the incoming "done" messages in cage reaction blocks or state machine transitions.
The "whitebox" PC application
The miniHILLib contains a basic python application in the minihillib/scripts/whitebox subfolder. This application is not meant to be run directly but through the runWhiteboxClient gradle command which will configure the required python interpreter and search paths.
Initial configuration
To be able to run the PC application some configuration is needed:
-
If you want to use the default openocd debugger interface: Download the CMSIS Pack for your target controller. Most packs can be found here: https://www.keil.arm.com/packs/ (optional)
-
Store the pack in any folder (you can configure the path later) (optional)
-
-
Configure your project whitebox configuration folder:
-
Create a new folder next to your
gradle.propertiesfile. -
Add a
whitebox_path=myFolderNameentry to thegradle.propertiesfile (the folder name is resolved relative to the gradle.properties file) -
In the newly created folder add a
config.inifile with the following content and configure your project:
-
[tools]
# Path to your packs folder
packs = ../../../../packs
[SUT]
# Path to your elf file. Also accepts .axf files and any other file format supported by pyocd.
elfFile = ../DUTProject/Build/target.elf
# or: elfFile = ../DUTProject/Build/target.axf
[debugger]
# Set the next line to false to disable the default pyocd debugger interface. When disabled it is not needed to configure the elfFile and packs.
enabled = true
[whitebox]
# If set to true, the whitebox client exits on connection loss or connect timeout.
# If set to false (default), it keeps running and retries until a connection to miniHIL is available.
exit_on_disconnect = false
-
If needed you may place a
pyocd.ymlfile in the same folder to further configure pyocd (https://github.com/pyocd/pyOCD/blob/main/docs/configuration.md#config-file)
To use the runCustom command we provide an example in the /miniHilLib/scripts/whitebox_template folder. You can copy the contained scripts into myFolderName/custom_scripts. With this example setup you only need to set debugger enabled = false in the config.ini file.
Model setup and white box client start
-
Add the whitebox port to your test actor:
-
In your test actor, add the following port:
Port whitebox: PWhiteboxRemote
-
-
Add the actor and binding to your application:
-
Add the
AWhiteboxRemoteactor and create a binding to your test actor:ActorRef whiteboxRemote: AWhiteboxRemoteandBinding whiteboxRemote.whitebox and tester.whitebox. -
Make sure to adapt the binding to match your test actor’s name.
-
-
Launch the GUI:
-
Start the GUI, but you don’t need to connect just yet.
-
-
Run the Python whitebox test client:
-
Run the whitebox client by executing:
.\gradlew.bat runWhiteboxClient -
The output should resemble the example output below (Example output from the whitebox client). The client will then sleep and wait for communication with miniHIL.
-
-
Add the example test step:
-
Insert the example test step (Example test step) into your
.cagefile and include it in a test suite.
-
-
Run the test:
-
Flash the device, connect, and execute the test while the whitebox script is still running. The test should pass, and you should see output in the console.
-
INFO:root:Custom runnables found.
INFO:root:
All available runnables:
{'dummy': <custom_scripts.dummy.DummyRunnable object at 0x0000013780544A88>}
miniHIL tcp client connected
Step runDummyWhiteboxRunnable:
timeout 10s
action
``Wb_runCustom("dummy", "SomeRandomParameter");``
reaction
expect whitebox.done == 1
;
You can create as many 'runnables' as you like. A runnable is a Python class with a run function that can be triggered by the miniHIL. All Python scripts are located in the 'whitebox/custom_scripts' folder within the MiniHILPilot directory. Two examples are provided in the dummy.py file. For the scripts to be called, they must also be added to the 'runnables' dictionary in the init.py file.
Additional ini options
| option | description |
|---|---|
[debugger].serial |
debugger serial number to connect to in case multiple debuggers are connected to the PC |
[debugger].enabled |
can be set to true or false to completely disable the built-in pyocd debugger interface. This can be used in case the target debugger is not compatible. You can then skip the packs and elf file configuration. |
The "multi channel pass through" functionality
The multi-channel pass-through functionality ensures that the interface remains fully transparent, allowing the user complete flexibility in implementing the specific protocol as needed. The difference compared to the whitebox test interface is that there are no fixed commands or a predefined application running on the PC. This allows data exchange to be specifically tailored to the use case, enabling a more flexible setup depending on the particular requirements of the scenario.
Multichannel Communication on the miniHIL
The functionality described below can be accessed on the miniHIL via the PMultiChannelComm Protocol, which is located in the minihil.platform.multichannel package. The functionality is provided as a Service and is accessed by adding a PMultiChannelComm SAP to your actor.
Operations that can be executed through PMultiChannelComm:
-
registerChannel(channelID: int8):This operation registers a new communication channel with a specific identifier (channelID). Once called, it establishes a communication pathway that allows for data exchange over the designated channel. The operation is crucial for enabling multi-channel communication and should be acknowledged by the connected device, ensuring that the channel is active and ready for use. Successful registration is confirmed through an acknowledgment message, and if the channel is lost, an unregistered message is sent. -
sendBytesbytes: uint8 ref, size: uint16:This operation facilitates the sending of a byte array to the registered channel. It takes two parameters: a reference to the byte array (bytes) and its size (size). The function internally sets the channel according to the previously registered channel ID and utilizes theMultiChannelComm_sendBytesfunction to perform the data transmission. -
sendPacket(packet: DStaticPacket ref):This operation allows for the transmission of a static packet over the registered channel. It takes a reference to aDStaticPacket, which encapsulates the data to be sent. Internally, this method callssendBytes, converting the packet’s buffer into a byte array and sending its length. -
allocBuffer(size: uint16):This operation allocates a buffer of a specified size for use with the registered channel. It returns a reference to the allocated buffer, which can be used later for data transmission. The buffer is intended for scenarios where data needs to be collected and sent in a batch, allowing for efficient use of resources. -
sendBuffer(buffer: uint8 ref, size: uint16):This operation sends a previously allocated buffer on the registered channel. It takes a reference to the buffer and its size, allowing for the transmission of data that has been prepared in advance. This method is particularly useful for applications that need to send large amounts of data or multiple packets in quick succession, as it minimizes the overhead of repeated allocations and improves throughput. The function utilizesMultiChannelComm_sendBufferto handle the actual sending of the data. -
isOpen():Checks if the communication channel is currently open. This function internally callsMultiChannelComm_isOpen(_channelId), which checks if the registered channel (identified by_channelId) is actively open for communication. If the channel is open, it returnstrue; otherwise, it returnsfalse. This is particularly useful for monitoring the status of the channel during multi-channel communication, ensuring that data is only sent through channels that are ready and open.
Messages that can be received by PMultiChannelComm:
-
registered():This message indicates that a channel has been successfully registered. Upon invoking theregisterChannel(channelID: int8)operation, the connected device sends this acknowledgment message to confirm that the communication channel is now active. This response is critical for ensuring that the application can proceed with further operations on that channel, providing feedback on the successful establishment of communication. -
unregistered():This message notifies the application that a previously registered channel has been lost or unregistered. It serves as a warning that the communication pathway is no longer available for data transmission. This message is important for error handling and for maintaining the integrity of the communication process, allowing applications to take appropriate actions, such as re-establishing the connection or notifying the user of the issue. -
receivedPacket(DStaticPacket)This message is triggered when a static packet is received from the registered channel. It includes a reference to theDStaticPacketthat encapsulates the incoming data. Proper handling of this message allows applications to process received data promptly and efficiently. -
channelOpened():This message indicates that a channel has been successfully opened for communication. It is sent by the connected device when the application initiates a communication channel and is successfully acknowledged. This notification allows the application to understand that it can begin data transmission, ensuring that all components are synchronized and ready for interaction. -
channelClosed():This message notifies the application that a channel has been closed, either by the application itself or by the connected device.
|
The registerChannel message must be send on each SAP before it can be used to send or receive data. |
Multichannel Communication on the PC
For the PC application handling multichannel communication, you need to develop an application that processes the incoming and outgoing data. If the passthrough is enabled, then while the GUI or headless test runner is running a TCP server is available and can be accessed at localhost:[3300 + ID] for communication.
To configure the project, you must add the following arguments to the gradle.properties file:
-
headless_test_args=--passthroughMultichannelIds [ID] -
hilsimgui_args=--passthroughMultichannelIds [ID]
|
The ID must be within the range [30…60] |