Skip to content

# Developing for M4

This chapter provides a short description on how to create and debug applications on the M4 coprocessor of the STM32MP1 with the help of example applications. For a more general and detailed description of the M4 functionality please refer to the STM32 MPU wiki by ST.

Provided demo applications

- m4_ktn_echo_CM4.elf (default)
  Simple application to illustrate communication between Linux and M4 by /dev/ttyRPMSG virtual UARTs.
- m4_ktn_simple-monitor.elf (outdated)
  Simple application to communicate thru /dev/ttyRPMSG and to control LEDs on the Kontron DK/BL boards. Outdated because it uses an older IDE version.
- m4_ktn-eval-usart6 (outdated)
  Demo application to demonstrate accessing the SOC UART component and how to partition the SOC components between Linux and M4 context. Outdated because it uses an older IDE version and requires the elder t1000-s BL/DK boards.

For Kontron images, the application `m4-application.elf` is loaded on boot. This is currently the same application as `m4_ktn_echo_CM4.elf`.

## Prerequisites

For M4 debugging you need an appropriate JTAG debugger. What we recommend is

- ST-Link/V2 debugger and
- Olimex LTD ARM-JTAG-20-10 connector

See the board documentation for the location of the debug plug. For Kontron BL/DK boars the outline of the debug plug can be found here.

Before continuing make sure that:

- A running linux image is present on your device
- The STM32CubeIDE is installed

## Debug modes of the M4 coprocessor

The M4 firmware can be run and debugged in two different modes:

- Production mode
  M4 firmware is loaded from network and started with the remoteproc service running on the A7.

- Engineering mode
  M4 firmware is loaded and started from the debugger similar to normal STM32 procedure. In this mode the A7 is not running.

Info

Due to a missing boot switch the engineering mode is currently not available for Kontron BL/DK boards. Thus, following description is for the production mode only.

More detailed information on the boot modes can be found in the ST wiki.

## Debugging the M4 coprocessor

This is a step by step guide how to debug the M4 example application on the Kontron BL/DK boards in production mode.

- Connect the debug console to the host (via USB interface)
- Connect the BL/DK board to the network and figure out the ip address with `ifconfig`
- Connect the ST-Link with Olimex connector to the board and the pc
- Open the CubeIDE
- Open or import the example project `m4_ktn_echo`
- Rebuild the project
- Right click on the project and go to `Debug as..`
- Double click `ST's STM32 MPU Debugging`
- Go to the `Startup` tab and input the ip address of your board
- Set a breakpoint at the start of `main()`
- Press `Debug` and input `root` as username and no password
- After confirming the log in data a few times, you should end up in the Debug view similar to normal STM32 microcontroller debugging.

The next section describes the capabilities of this application and how to use it.

## Description of the `m4_ktn_echo` example application

This example is based on the `OpenAMP_TTY_echo` example application from ST which can be found here. It will create one virtual uart channel between the A7 and the M4 cores based on the Linux frameworks RPMsg, VirtIO and IPCC and the OpenAmp framework on the M4 side.

As the name implies, the application offers a simple echo server which echoes all incoming messages back to Linux.

## Creating a new project

New projects might be created with the CubeIDE or by taking the ST template from https://github.com/STMicroelectronics/STM32CubeMP1. This repository also includes all HAL_Drivers and lots of examples which can be used for building your application.

However, these example applications are designed for the evaluation boards of ST and have complex include paths structures which are not very friendly for extracting project parts like the OpenAMP framework.

For Kontron SOM and BL/DK boards appropriate CubeIDE projects can be found in the directory `conf/machine/cubemx` in `meta-ktn-stm32` layer. These projects already contain the correct clock tree and pinmux settings for these devices and might be a good starting point for your own project.

Using the `m4_ktn_echo` might be less stressful to use as starting point for your own project, as it includes the rsc_table, basic Drivers and system libraries as well as all necessary header and source files.

## Assigning peripheral devices to the M4 coprocessor

To use a peripheral device with the M4 coprocessor it has to be assigned to it in the device tree prior to the Linux boot. This can be accomplished by creating your own board device tree overlay. For the Kontron BL/DK boards there is a file `stm32mp-board-k-m4-uart.dtsi` which removes USART3 (RS232) form Linux context and assigns to M4 context.

In the following the usart3 peripheral is taken as an example. On the Kontron BL/DK boards the usart3 is available as RS232 interface on connector X16.

First of all, the respective node has to be disabled for A7 cores with Linux and enabled for the M4. This can be accomplished by adding:

    /* Disable usart3 for linux and enable m4 resource */
    &usart3{
        status = "disabled";
    };
    &m4_usart3{
        status = "okay";
    };

Normally a M4 application called `m4-application.elf` will be loaded and started on boot. To change the M4 applilcation to be loaded, a device tree entry can be set like this:

    / {
        /* Load M4 demo application */
        m4-application = "m4-ktn-demo";
    };

To rebuild the device tree, either build the respective image or only the Linux kernel image with `bitbake linux-stm32mp`.

Afterwards replace the old device tree in the boot directory and reboot the board. To check if the resource is really disabled for the A7, read out the node status with `cat /proc/device-tree/soc/serial\@4000f000/status`. Additionally check if the M4 resource was enabled successfully with `cat /proc/device-tree/m4\@0/m4_system_resources/serial\@4000f000/status`.

Additionaly, for an easy and graphical configuration of a new peripheral the CubeIDE tool can be used to generate the project. As a starting point the CubeIDE project with the initial evaluation board configuration can be used, which can be found in the `meta-ktn-stm32mp` layer at `conf/machine/cubemx`. Here, it is again simplier to take the initialization of the respective peripheral from the project created by CubeMX and use it in an already working project.

When sharing peripheals between Linux and M4 the resource manager could also get interesting.

Also some stronger protection of the M4 peripheals can be activated in tf-a bootloader for every peripheal which is used exclusively by M4. This requires creating and compiling your own adapted tf-a bootloader.

More detailed informations on assigning peripheral devices can be found in the ST wiki.

## Starting Software with system service

A system service called `m4-autoload.sh` is included in the Kontron Linux images. It loads and starts the examples on system boot. The service can be controlled with the commands `start` and `stop`. For example this stops the M4 processor:

`/etc/init.d/m4-autoload.sh stop`

If you want to start your own M4 appllication, you have to adapt the `APPLICATION_NAME` entry in `/etc/default/m4-autoload.conf` to your needs.

If you want to include your own binary file into the service when building your yocto image, you need to add some adaptions in your own yocto layer.

- either exchange the `m4-appliction.elf` file with your own copy
- or adapt the `m4-autoload.conf` file to your needs

In every case you have to create a recipe append file called `m4-autoload.bbappend` in `recipes-extended/m4-autoload` directory which references your binary M4 application file from `recipes-extended/m4-autoload/files/binary`.

## Starting software manually

In case the system service is not used, the M4 firmware can be started manually with the following principle

- Copy or link the binary file into `/lib/firmware`
- Publish the file name which contains the application binary
  `echo -n "my-application.elf" > /sys/class/remoteproc/remoteproc0/firmware`
- Load and start M4 application `echo -n start > /sys/class/remoteproc/remoteproc0/state`
- Read the state of M4
  `cat /sys/class/remoteproc/remoteproc0/state`
- stop the M4 application `echo -n stop > /sys/class/remoteproc/remoteproc0/state`

Alternatively you can also use the `m4-autostart` script available in the Kontron images.

## Getting logs from M4

For all of the demo projects a trace buffer is added to the resource table. This enables reading out the log buffer of M4 in the Linux context:

    root@stm32mp-t1000-s-multi:~# cat /sys/kernel/debug/remoteproc/remoteproc0/trace0
    [00000.000][INFO ]Cortex-M4 boot successful with STM32Cube FW version: v1.0.0
    [00000.008][INFO ]Virtual UART0 OpenAMP-rpmsg channel creation
    [00000.009][INFO ]Virtual UART1 OpenAMP-rpmsg channel creation