Last edited one month ago

Modify, rebuild and reload a firmware


1. Overview[edit | edit source]

This stage explains how to modify, rebuild, and reload an STM32MP1 Arm® Cortex®-M4 coprocessor firmware.

It proposes to customize the STM32MP1Cube package application example OpenAMP_TTY_Echo using STM32CubeIDE.

2. Disconnect the "minicom" console[edit | edit source]

  • If minicom is already opened, please disconnect it to use the STM32CubeIDE built-in serial console.
Ctrl + A then Q

3. Open STM32CubeIDE[edit | edit source]

  • Start STM32CubeIDE.
STM32CubeIDE Starter Screen


  • Choose a workspace (default is fine).
  • Notice information provided in the Information Center page and close it. (You can open it later.)
STM32CubeIDE Information Center Page


  • Go into your workspace projet view.


STM32CubeIDE Project View

4. Import an existing example in STM32CubeIDE[edit | edit source]

  • In the File menu, select Import. Then, choose Existing Project into Workspace.
STM32CubeIDE import screen
  • Browse and select the OpenAMP_TTY_echo application example in the folder matching your board :

$HOME/STM32MPU_workspace/STM32MPU-Ecosystem-v6.0.0/Developer-Package/STM32Cube_FW_MP1_V1.7.0/Projects/STM32MP157C-DK2/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE

or

$HOME/STM32MPU_workspace/STM32MPU-Ecosystem-v6.0.0/Developer-Package/STM32Cube_FW_MP1_V1.7.0/Projects/STM32MP157C-EV1/Applications/OpenAMP/OpenAMP_TTY_echo/STM32CubeIDE


  • STM32CubeIDE brings a specific project structure for dual-core devices such as STM32MP1. A top-level project contains sub-projects for each core.
  • Here, the OpenAMP_TTY_echo top project contains the OpenAMP_TTY_echo_CM4 sub-project. Keep the two projects selected and click on Finish.
STM32CubeIDE project selection
  • The OpenAMP_TTY_echo project is open, and you can browse inside using the left panel.
OpenAMP_TTY_echo project structure

5. Build the firmware[edit | edit source]


  • In the OpenAMP_TTY_Echo_CM4 project, click the Build button (the little hammer in the toolbar).
STM32CubeIDE build the project


  • "Build" is finished with no errors.
STM32CubeIDE build finished with no error

6. Check connection to the target[edit | edit source]

STM32CubeIDE requires a connection to Linux running on an STM32MP1 device though 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 :

STM32CubeIDE Serial Console button

The connection is correct if the Linux log or prompt is displayed in the console window.

STM32CubeIDE Linux Prompt

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.

STM32Cube Serial Target widget status

In case of different statuses such as busy or console in use, check that you have no other terminal connected and close the console.

In case of a different status such as Stopped, right-click on it and select Start.

7. Start Debug Session[edit | edit source]

  • Click on your OpenAMP_TTY_echo_CM4 project to select it.
  • If not already created, create your debug configuration by right-clicking on OpenAMP_TTY_echo_CM4 and selecting Debug As and STM32 C/C++ Application. It will open the Edit Configuration window.
Select Production mode in Startup pane of Debug Configuration
  • Check if the IP address is correctly filled (1). Otherwise, you can force detection using the button on the right (2).
  • Ensure the Thru Linux core (production mode)" is selected (3).
  • When the configuration is correct, the Debug button (5) becomes active, and you can launch the debug session. Otherwise, an error message appears in area (4).

STM32CubeIDE needs to use a serial connection to the board to manage firmware download.
If the console is open, it will request your approval to close it. Answer yes.

SSH password popup

The debug in "production mode" adds the Cortex-M firmware transfer to the embedded Linux. In case of network usage, some specific pop-up appears:

  • The SSH Password must be completed: the default one is root.
SSH password popup
  • the RSA key must be approved.
RSA key popup


After firmware download, STM32CubeIDE switches into the Debug Perspective.

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.

For further information, refer to STM32CubeIDE documentation avaialble inmy.st.com

8. Test the firmware[edit | edit source]

The OpenAMP_TTY_echo_CM firmware performs the following:

  • CPU2(CM4) initializes OpenAMP middleware, which initializes and configures the IPCC peripheral through HAL and sets up the OpenAMP-RPMsg framework infrastructure.
  • CPU2(CM4) creates two RPMsg channels for two virtual UART instances (UART0 and UART1).
  • CPU2(CM4) waits for messages from CPU1(CA7) on both channels.
  • When CPU2(CM4) receives a message on one Virtual UART instance/RPMsg channel, it sends the message back to CPU1(CA7) on the same virtual UART instance.

Reopen the serial console of STM32CubeIDE and enter following commands :

  • Initialize the ttyRPMSG0 configuration.
stty -onlcr -echo -F /dev/ttyRPMSG0
  • Read constantly the ttyRPMSG0 channel in background.
cat /dev/ttyRPMSG0 &
  • Send a message on one ttyRPMSG0 channel 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 ttyRPMSG1 channel.
  • Terminate the STM32CubeIDE debug session will stop the firmware.

9. 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 on which channel the message is received on, we propose modifying the firmware to add an indication to identify the channel receiving the message.

To do this, please modify the original main.c 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.

10. Testing the modified firmware[edit | edit source]

10.1. Relaunch debug session[edit | edit source]

  • By clicking on the Debug button, STM32CubeIDE relaunches the debug session after performing an incremental build to take into account your modification.
  • If everything is correct, you will switch back to the Debug Perspective window after reloading the new firmware.

10.2. Test[edit | edit source]

  • Initialize the ttyRPMSG0 and ttyRPMSG1 configurations.
stty -onlcr -echo -F /dev/ttyRPMSG0
stty -onlcr -echo -F /dev/ttyRPMSG1
  • Read constantly the ttyRPMSG0 and ttyRPMSG1 channels in the background.
cat /dev/ttyRPMSG0 &
cat /dev/ttyRPMSG1 &
  • Send a message on one ttyRPMSG0 channel and check the echo log.
echo "Hello Virtual UART0" > /dev/ttyRPMSG0
Channel RPMSG0: Hello Virtual UART0
  • Send a message on one ttyRPMSG1 channel and check the echo log.
echo "Hello Virtual UART1" > /dev/ttyRPMSG1
Channel RPMSG1: Hello Virtual UART1



  • Terminate the STM32CubeIDE debug session.