1. Overview[edit | edit source]
This stage explains how to modify, rebuild, and reload an STM32MP2 Arm® Cortex®-M33 coprocessor firmware.
It proposes to customize the STM32MP2Cube package application example, named OpenAMP_TTY_Echo, using STM32CubeIDE.
2. Software prerequisites[edit | edit source]
- Boot from SD card with ecosystem release   v6.1.0  , using , using- For STM32MP257F-DK Discovery kit  for STM32MP23x lines evaluation for STM32MP23x lines evaluation : FlashLayout_sdcard_stm32mp235f-dk-fastboot.tsv : FlashLayout_sdcard_stm32mp235f-dk-fastboot.tsv
- For STM32MP257x-DK Discovery kit  : FlashLayout_sdcard_stm32mp257f-dk-ca35tdcid-ostl-m33-examples-optee.tsv : FlashLayout_sdcard_stm32mp257f-dk-ca35tdcid-ostl-m33-examples-optee.tsv
- For STM32MP257x-EV1 Evaluation board  : FlashLayout_sdcard_stm32mp257f-ev1-ca35tdcid-ostl-m33-examples-optee.tsv, : FlashLayout_sdcard_stm32mp257f-ev1-ca35tdcid-ostl-m33-examples-optee.tsv,
 
- For STM32MP257F-DK Discovery kit 
- STM32CubeIDE installation explained in this article, if not already done in previous steps
- Install build environment
- 1-Install dependencies:
 
sudo apt-get install -y git curl wget build-essential libssl-dev python3 \
           python3-pip cmake make libncurses5
- 2-Add CMake path into environment:
 
export PATH=<CMake path>/bin:$PATH
- 3-Verify cmake version:
 
cmake --version
- 4-Use cmake at least or newer than 3.22.1.
 
- Install Python libraries needed by OP-TEE signature Python script.
pip install pyelftools pip install pycryptodomex
3. Disconnect the "minicom" console[edit | edit source]
- If minicomis already open, disconnect it to use the STM32CubeIDE built-in serial console.
Ctrl + A then Q
4. Open STM32CubeIDE[edit | edit source]
- Start STM32CubeIDE
- Choose a workspace (default is fine).
- Notice the information provided on the Information Center pageand close it. (You can open it later.)

 
- Go into your workspace project view.

5. Import an existing example in STM32CubeIDE[edit | edit source]
- In the Filemenu, selectImport. Then, chooseExisting Project into Workspace.
- Browse and select the OpenAMP_TTY_echoapplication example in the folder matching your board :- For STM32MP257F-DK Discovery kit  for STM32MP23x lines evaluation for STM32MP23x lines evaluation : $HOME//STM32MPU_workspace/STM32MPU-Ecosystem-v6.1.0/Developer-Package/STM32Cube_FW_MP2_V1.2.0/Projects/STM32MP235F-DK/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE, : $HOME//STM32MPU_workspace/STM32MPU-Ecosystem-v6.1.0/Developer-Package/STM32Cube_FW_MP2_V1.2.0/Projects/STM32MP235F-DK/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE,
- For STM32MP257x-DK Discovery kit  : $HOME//STM32MPU_workspace/STM32MPU-Ecosystem-v6.1.0/Developer-Package/STM32Cube_FW_MP2_V1.2.0/Projects/STM32MP257F-DK/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE, : $HOME//STM32MPU_workspace/STM32MPU-Ecosystem-v6.1.0/Developer-Package/STM32Cube_FW_MP2_V1.2.0/Projects/STM32MP257F-DK/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE,
- For STM32MP257x-EV1 Evaluation board  : $HOME//STM32MPU_workspace/STM32MPU-Ecosystem-v6.1.0/Developer-Package/STM32Cube_FW_MP2_V1.2.0/Projects/STM32MP257F-EV1/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE. : $HOME//STM32MPU_workspace/STM32MPU-Ecosystem-v6.1.0/Developer-Package/STM32Cube_FW_MP2_V1.2.0/Projects/STM32MP257F-EV1/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE.
 
- For STM32MP257F-DK Discovery kit 
- STM32CubeIDE brings a specific project structure for dual-core devices such as STM32MP2. A top-level project contains sub-projects for each core.
- Here, the OpenAMP_TTY_echotop project containsOpenAMP_TTY_echo_CM33_NonSecureandOpenAMP_TTY_echo_CM33sub-projects. Keep the three projects selected and click on "Finish".
- The OpenAMP_TTY_echoproject is open, and you can browse inside using the left panel.
6. Build the firmware[edit | edit source]
- Select project OpenAMP_TTY_Echo_CM33_NonSecureand chooseCA35TDCID_m33_ns_signbuild configuration (the little arrow on the right of the hammer in the toolbar). By default,CA35TDCID_m33_nsis selected.

- "Build" is finished with no errors.

7. Check connection to the target[edit | edit source]
STM32CubeIDE requires a connection to Linux® running on an STM32MP2 device though a serial connection.
This connection is automatically detected and configured when you connect the cable to the ST-Link port and the board has booted. 
You can check if you can get the Linux® log and prompt by clicking on the STM32 butterfly button : 
Connection is correct if the Linux® log or prompt is displayed in the console window.
Your board might be connected to the PC by Ethernet, either using RJ45 (point-to-point or VLAN) or USB0 EthernetOverUSB gadget (point-to-point connection with PC using TypeA-TypeC cable). The screenshot below uses the second solution. 
When a serial connection is established, STM32CubeIDE automatically detects the board IP address and displays it in the Serial Target widget status window in the bottom right part of the screen. 
In case of different statuses such as busy or console in use, check that you have no other terminal connected and close the console.
Also, check that the preferred device is /dev/ttyACM0 in the menu Window > Preferences > STM32Cube > MPU Serial:
Furthermore, if the status is Stopped, right-click there and then click on Start:
8. Start Debug Session[edit | edit source]
- Click on your  OpenAMP_TTY_echo_CM33_NonSecureproject to select it.
- With the arrow right of the hammer sign, choose the project configuration with _signin the name, then it builds it.
- If not already created, you will need a run configuration (to load without debug) and a debug configuration (to debug without download).
- Run configuration: create it by right-clicking on " OpenAMP_TTY_echo_CM33_NonSecureand selectingRun AsandSTM32 C/C++ Application. It opens theEmbedded C/C++ Applicationwindow.

- Click the OKbutton. It opens theEdit the Configurationwindow. You may modify the name of the run configuration and must replaceCA35TDCID_m33_ns_sign/OpenAMP_TTY_echo_CM33_NonSecure.elfwithCA35TDCID_m33_ns_sign/OpenAMP_TTY_echo_CM33_NonSecure_sign.binas shown in the following picture and press theOKbutton.

- The other tabs of the configuration should be fine by default. To check the IP, in the debugger tab you can check if the address is correctly filled.
- Make sure the Thru Linux core(production mode) is selected.
- When the configuration is correct, click on OK.
- To run the configuration, first click on the arrow right on the run button and then click on Run Configurations...
- When the Run Configurationswindow is open, select the user configuration and click on theRunbutton. The binary file is loaded. After this step, the user configuration appears in the menu of theRunbutton.
- Now the firmware is loaded. To debug it, a debug configuration is needed. Create it by right-clicking on OpenAMP_TTY_echo_CM33_NonSecureand selectingDebug AsandSTM32 C/C++ Application. It will open theEmbedded C/C++ Applicationwindow.

- In the Edit the Configurationwindow, click theOKbutton. Click on the Startup tab and select the file. You may modify the name by adding_Debug.

- Then click on the Editbutton, in theAdd/Edititem, uncheckDownloadand clickOK.

- Click OK in the Edit Configuration where there is a False for the download.

- The debug perspective is started. If not, proceed in the same way as the run configuration but with the debugbutton instead. Press thesuspendbutton, and the firmware will stop as shown here:

In "production mode", the firmware does not break at main. GDB is simply attached to the running target. You can then use all features of the debugger.
|  Information | 
| To benefit of the best GDB debug experience it's recommended to upgrade the onboard ST-Link version with the latest release. You can simply do it from STM32CubeIDE using menu "Help -> ST-Link Upgrade" | 
For further information, refer to the STM32CubeIDE documentation available on my.st.com.
9. Test the firmware[edit | edit source]
The OpenAMP_TTY_echo_CM33 firmware do the following:
- CPU2(CM33) initializes OpenAMP middleware which initializes/configures IPCC peripheral through HAL and setup openamp-rpmsg framework infrastructure,
- CPU2(CM33) creates 2 rpmsg channels for 2 virtual UART instances (UART0 and UART1),
- CPU2(CM33) is waiting for messages from CPU1(CA35) on these both channels,
- When CPU2(CM33) receives a message on 1 Virtual UART instance/rpmsg channel, it sends the message back to CPU1(CA35) on the same Virtual UART instance.
Reopen the Serial console of STM32CubeIDE and enter following commands :
- Initialize the ttyRPMSG0configuration.
stty -onlcr -echo -F /dev/ttyRPMSG0
- Read constantly the ttyRPMSG0channel in background
cat /dev/ttyRPMSG0 &
- Send a message on one ttyRPMSG0channel and receive the echo on the same ttyRPMSG0 channel.
echo "Hello Virtual UART0" > /dev/ttyRPMSG0 Hello Virtual UART0
- You can perform the same steps with the ttyRPMSG1channel.
- Terminate the STM32CubeIDE debug session will stop the firmware.
10. Modify the firmware[edit | edit source]
The original firmware example receives a message for the host on one channel and acknowledges by returning the same message to the host on the same channel.
As it is not obvious which channel receives the message, we propose modifying the firmware to add an indication of the channel receiving the message.
To do this, modify the main.c original code as follows:
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    OPENAMP_check_for_message();
    /* USER CODE END WHILE */
    if (VirtUart0RxMsg) {
      char msg_to_transmit[MAX_BUFFER_SIZE];
      int msg_size = 0;
      VirtUart0RxMsg = RESET;
      msg_size = snprintf(msg_to_transmit, MAX_BUFFER_SIZE, "Channel RPMSG0: ");
      msg_size += snprintf(msg_to_transmit + msg_size, MAX_BUFFER_SIZE, "%s\n", VirtUart0ChannelBuffRx);
      log_info("size of the message to transmit = %d bytes\n", msg_size);
      VIRT_UART_Transmit(&huart0, (uint8_t*)msg_to_transmit, msg_size);
    }
    if (VirtUart1RxMsg) {
      char msg_to_transmit[MAX_BUFFER_SIZE];
      uint16_t msg_size = 0;
      VirtUart1RxMsg = RESET;
      msg_size = snprintf(msg_to_transmit, MAX_BUFFER_SIZE, "Channel RPMSG1: ");
      msg_size += snprintf(msg_to_transmit + msg_size, MAX_BUFFER_SIZE, "%s\n", VirtUart1ChannelBuffRx);
      log_info("size of the message to transmit = %d bytes\n", msg_size);
      VIRT_UART_Transmit(&huart1, (uint8_t*)msg_to_transmit, msg_size);
    }
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
- Save your modifications.
- Then open the properties of the project by right-clicking on it and selecting Properties.
Go to C/C++ Build > Settings > MCU GCC Compiler > Preprocessor.
Add a new symbol: __LOG_TRACE_IO_.
This symbol will enable the log_info macro.
11. Testing the modified firmware[edit | edit source]
11.1. Relaunch debug session[edit | edit source]
- By clicking on the Runbutton, as explained in the Start Debug Session chapter, you can download the firmware. Then, by clicking on theDebugbutton, the STM32CubeIDE relaunches the debug session after performing an incremental build to account for your modifications.
- If everything is correct, you will switch back to the Debug Perspectivewindow after reloading the new firmware.
11.2. Test[edit | edit source]
- Initialize the ttyRPMSG0andttyRPMSG1configurations.
stty -onlcr -echo -F /dev/ttyRPMSG0 stty -onlcr -echo -F /dev/ttyRPMSG1
- Read constantly the ttyRPMSG0andttyRPMSG1channels in the background.
cat /dev/ttyRPMSG0 & cat /dev/ttyRPMSG1 &
- Send a message on one ttyRPMSG0 channeland check the echo log.
echo "Hello Virtual UART0" > /dev/ttyRPMSG0 Channel RPMSG0: Hello Virtual UART0
- Send a message on one ttyRPMSG1channel and check the echo log.
echo "Hello Virtual UART1" > /dev/ttyRPMSG1 Channel RPMSG1: Hello Virtual UART1
|  Information | 
| When the firmware is running, you can output log from the firmware by using the following command: cat /sys/kernel/debug/remoteproc/remoteproc0/trace0 | 
- Terminate the STM32CubeIDE debug session.
12. To go further[edit | edit source]
If you want to build and debug a secure project, refer to How_to_build_and_debug_secure_project_on_STM32MP25_co-processor_in_STM32CubeIDE
 
 
 
 
 
   
   
   
   
   
   
   
   
   
   
  



