Problem with re-flashing M4 core on iMX8MM

I am trying to load firmware to M4 core on iMX8MM without rebooting the system. I am using J-Link for flashing and debugging.

Since I am using RPMSG, the M4 app is stuck on rpmsg_lite_is_link_up() function upon re-flashing. I managed to get this to work by calling virtqueue_kick() from user-space on A53 core by using imx-m4fwloader (with modifications described in this post). M4 application then continues to run normally and it can receive RPMSG messages.

However, I noticed that the program crashes when calling basic FreeRTOS functions like vPortYield() or vTaskEnterCritical(). I get SIGTRAP in the debugger even though there are no breakpoints or watchpoints, and I’m not able to print stack trace or resume the program.

The program works normally when I use the standard procedure for flashing (restarting the board, stopping U-Boot and flashing M4 core).

Has anyone had similar problems? Is there any other way to get RPMSG to work after M4 reset?

Greetings @ksalamun!

Can you share an example so I can try reproducing that on my side?

My best guess, for now, is that this might have something to do with the RPMsg driver on the Linux side. I think the Linux side might not be aware of the changes on the M4 side. Did you try reloading the RPMsg kernel module on Linux?
Does this work if you reboot Linux after reflashing the M4 core?

Thank you for your response!

Here is a minimal example based on the NXP SDK ping-pong example: GitHub - KarlaSalamun/iMX8MM_example
Project setup is based on VSCode (I followed this tutorial).

Here are the steps to reproduce the issue:

  • power up the development board, interrupt U-Boot and flash M4 firmware through VSCode debugger and continue booting Linux

  • modprobe the imx-rpmsg-tty kernel module

  • at this point everything should work normally when you try to send a message to /dev/ttyRPMSG30 (the message should be printed on M4 uart)

  • stop M4 core from VSCode debugger

  • remove imx-rpmsg-tty kernel module: modprobe -r imx-rpmsg-tty

  • reload the module: modprobe imx-rpmsg-tty

  • flash M4 again - the code will now hang at rpmsg_lite_is_link_up() function

  • use m4fwloader to ping the M4 core from user-space: ./m4fwloader kick 0

  • I get the following output in the Linux debug console:

    [ 177.351422] virtio_rpmsg_bus virtio0: channel rpmsg-openamp-demo-channel:ffffffff:1e already exist
    [ 181.910236] virtio_rpmsg_bus virtio0: rpmsg_create_channel failed

At this point, when I try to send a message to the serial port, the console hangs and the system reboots after a few minutes.

Unfortunately, I cannot reboot Linux as you suggested because I have a combination of Verdin SoM and carrier board where the power gets killed upon reboot, so M4 restarts as well.


Thanks for the feedback!

Honestly I don’t think that will be the issue, but did you try reloading the module after reflashing the M4? This would be the usual behavior when Linux boots.

I tried that as well, but it did not help - when I reload the module, the console hangs and the only thing I can do is reset the board.


We’re seeing many issues with the M cores on the latest downstream kernel from NXP. Our BSP does not officially support any M core functionality as of now, but we’re actively working to integrate some official support.

My suggestion, for now, is for you to use the default way of loading the firmware to the M4, which is via U-Boot. Unfortunately we didn’t test m4fwloader yet, but it’s something that’s planned for us to support.