[BBAI64] R5F cores firmwares and remoteproc questions

Hello guys,

I’m currently using the BBAI64 board, with Linux Image 5.10.168-ti-arm64-r118.
I’m dealing with R5F’s from the main domain.

k3conf dump processor
|--------------------------------------------------------------------------------|

VERSION INFO
K3CONF
SoC
SYSFW
--------------------------------------------------------------------------------

|--------------------------------------------------------------------------------------|
| Device ID | Processor ID | Processor Name | Processor State | Processor Frequency |
|--------------------------------------------------------------------------------------|
| 202 | 32 | A72SS0_CORE0 | DEVICE_STATE_ON | 2000000000 |
| 203 | 33 | A72SS0_CORE1 | DEVICE_STATE_ON | 2000000000 |
| 142 | 3 | C66SS0_CORE0 | DEVICE_STATE_OFF | 1350000000 |
| 143 | 4 | C66SS1_CORE0 | DEVICE_STATE_OFF | 1350000000 |
| 15 | 48 | C71SS0 | DEVICE_STATE_OFF | 1000000000 |
| 250 | 1 | MCU_R5FSS0_CORE0 | DEVICE_STATE_ON | 1000000000 |
| 251 | 2 | MCU_R5FSS0_CORE1 | DEVICE_STATE_ON | 1000000000 |
| 245 | 6 | R5FSS0_CORE0 | DEVICE_STATE_ON | 1000000000 |
| 246 | 7 | R5FSS0_CORE1 | DEVICE_STATE_ON | 1000000000 |
| 247 | 8 | R5FSS1_CORE0 | DEVICE_STATE_OFF | 1000000000 |
| 248 | 9 | R5FSS1_CORE1 | DEVICE_STATE_OFF | 1000000000 |
|--------------------------------------------------------------------------------------|

I have a few questions :
Why DSP’s are not booted ?
dmesg | grep dsp
[ 8.428266] k3-dsp-rproc 4d80800000.dsp: assigned reserved memory node vision-apps-c66-dma-memory@a9000000
[ 8.439261] k3-dsp-rproc 4d80800000.dsp: configured DSP for remoteproc mode
[ 8.557667] k3-dsp-rproc 4d80800000.dsp: local reset is deasserted for device
[ 8.587991] remoteproc remoteproc12: 4d80800000.dsp is available
[ 8.591683] k3-dsp-rproc 4d81800000.dsp: assigned reserved memory node vision-apps-c66-dma-memory@a8000000
[ 8.592405] k3-dsp-rproc 4d81800000.dsp: configured DSP for remoteproc mode
[ 8.605912] k3-dsp-rproc 4d81800000.dsp: local reset is deasserted for device
[ 8.617674] remoteproc remoteproc13: 4d81800000.dsp is available
[ 8.620042] k3-dsp-rproc 64800000.dsp: assigned reserved memory node vision-apps-c71-dma-memory@aa000000
[ 8.624835] k3-dsp-rproc 64800000.dsp: configured DSP for remoteproc mode
[ 8.631810] remoteproc remoteproc14: 64800000.dsp is available
[ 8.635057] remoteproc remoteproc12: powering up 4d80800000.dsp
[ 8.657201] k3-dsp-rproc 4d80800000.dsp: mbox_request_channel failed: -517
[ 8.664187] remoteproc remoteproc12: can’t start rproc 4d80800000.dsp: -16
[ 8.671474] remoteproc remoteproc13: powering up 4d81800000.dsp
[ 8.674237] k3-dsp-rproc 4d81800000.dsp: mbox_request_channel failed: -517
[ 8.681206] remoteproc remoteproc13: can’t start rproc 4d81800000.dsp: -16
[ 8.872233] remoteproc remoteproc14: powering up 64800000.dsp
[ 8.878995] k3-dsp-rproc 64800000.dsp: mbox_request_channel failed: -517
[ 8.885759] remoteproc remoteproc14: can’t start rproc 64800000.dsp: -16

It seems that the mailbox is not available so remoteproc can’t instantiate the cores, but from userspace I can start/stop DSP’s (with echo start/stop > /sys/class/remoteproc/remoteproc{nb}/state.

We see that 2 R5F are booted, and the two others are not.

I can’t start the two R5F which are off. Why ?
root@BeagleBone:~# cat /sys/class/remoteproc/remoteproc18/name
5e00000.r5f
root@BeagleBone:~# echo start > /sys/class/remoteproc/remoteproc18/state
-bash: echo: write error: No such file or directory

cat /sys/class/remoteproc/remoteproc16/state
running
root@BeagleBone:~# cat /sys/class/remoteproc/remoteproc18/state
offline

I have seen on different topic on TI website that the dual core R5F are “lockstep” by default. Is it the case with the BBAI64 Image ? How to change (to split mode) this in the devicetree ?

By default, I see that the firmware loaded on the different cores are defined here :
ls -l /lib/firmware/ | grep j7
-rw-r–r-- 1 root root 187480 Jul 5 2023 j7-c66_0-fw.tisdk
-rw-r–r-- 1 root root 187480 Jul 5 2023 j7-c66_1-fw.tisdk
-rw-r–r-- 1 root root 10489872 Jul 5 2023 j7-c71_0-fw.tisdk
-rw-r–r-- 1 root root 78708 Jul 5 2023 j7-main-r5f0_0-fw.tisdk
-rw-r–r-- 1 root root 78708 Jul 5 2023 j7-main-r5f0_1-fw.tisdk
-rw-r–r-- 1 root root 78708 Jul 5 2023 j7-main-r5f1_0-fw.tisdk
-rw-r–r-- 1 root root 78708 Jul 5 2023 j7-main-r5f1_1-fw.tisdk
-rw-r–r-- 1 root root 176304 Jul 5 2023 j7-mcu-r5f0_0-fw.tisdk
-rw-r–r-- 1 root root 78708 Jul 5 2023 j7-mcu-r5f0_1-fw.tisdk
root@BeagleBone:~# ls -l /lib/firmware/vision_apps_eaik_8.2/
total 16644
-rw-r–r-- 1 root root 1461044 Oct 28 2022 vx_app_rtos_linux_c6x_1.out
-rw-r–r-- 1 root root 1461012 Oct 28 2022 vx_app_rtos_linux_c6x_2.out
-rw-r–r-- 1 root root 13242432 Oct 28 2022 vx_app_rtos_linux_c7x_1.out
-rw-r–r-- 1 root root 572788 Oct 28 2022 vx_app_rtos_linux_mcu2_0.out
-rw-r–r-- 1 root root 297932 Oct 28 2022 vx_app_rtos_linux_mcu2_1.out

Where is the source code of these firmwares ?
Is it possible to load my own firmware on mcu2_0/1, and using the TIDL in parallel (on DSP’s ?)

Thanks in advance,
Valentin

I strongly suggest switching to the 6.12 firmware. It is now mostly usable. Are you using the edge AI stuff, or do you want to run your own code on the auxiliary cores?

Anyway, whether the cores are configured for locksetup or split, they can be changed with an overlay I believe. Here are the locations where the modes are configured in k3-j721e-main.dtsi for kernel 6.12. For r5fss0 BeagleBoard-DeviceTrees/src/arm64/k3-j721e-main.dtsi at 100884db5ca038af3a9c56c6142aa2067662218a · beagleboard/BeagleBoard-DeviceTrees · GitHub, and for r5fss1 BeagleBoard-DeviceTrees/src/arm64/k3-j721e-main.dtsi at 100884db5ca038af3a9c56c6142aa2067662218a · beagleboard/BeagleBoard-DeviceTrees · GitHub.

If you want to run your own code on an R5 I got this example application I am working on GitHub - kevinacahalan/BeagleBoneAI64_Heterogeneous_App_Example: An example application showing a heterogeneous app with Linux and R5 cores working together.

Hello Kevin !

First of all, sorry for my delayed response. Thank you very much for your detailed answer and for the time you gave. I like your project and it will for sure help me in the future.

I see you are using the minimal image which is not graphical. I will have to use the mini-DP port to send a video from a camera to a screen. It should not impact the software running on the R5F, no ?

Here is the global architecture of my project :

  • On R5FSS0 (or 1) : a software which uses GPIO + UART (need to be real time), maybe the use of RTOS whill help to implement the scheduling of the software ? I have an interruption on the GPIO which schedules different tasks. There is also a communication with the Linux Side, (maybe via rpmsg ?) which tells the R5F what to do (launch task 1, task 2, what is the current state of the task 3…)
  • On DSP C71 (maybe also on DSPs C66?) a software with one or two tasks and a communication with Linux with RPMSG, and also a shared memory with the Linux side (to exchange data).
  • On Linux side : Camera + UART + Remote cores + Send the video from the camera to mini DP + manage tasks on the remote cores.

Do you think it’s possible ? What do you think about using RTOS on remote cores ?
What are differences between R5FSS0 and R5FSS1. What is running on these cores by default ?

Thank you very much,

Valentin

Should be plenty possible.

What is up with the DSP? Any particular reason to use a DSP instead of another R5 core? If you really need to use a DSP you can start from this minimal DSP example and this DSP setup

Battles to fight with

  • You’ll need to figure out interrupt routing for GPIO interrupts for the R5s. I fought with trying to figure out and understand this for several weeks. Ended up moving on to other things… Maybe you can get away with a polling loop? Maybe you could figure out some magic to add to a DT overlay? My non-working setup
  • You will not have the GPU to help you with the camera. Might hit some unusable lag? I have no experience with any of this camera stuff, no real idea…
  • A nice setup for remoterproc talking between Linux and R5. I am currently working on this RN. If you look at my example code there is currently some sketchy mess to look at. I should have a nicer setup pushed next week
  • UART from Linux is currently not working with the kernel 6.12 Beaglebone Image. The driver loads, but no symlink. Maybe use 6.6 until the issue is fixed? Maybe the issue will be fixed next week, no idea. relevant message in BB discord
  • UART from R5. I have only tested UART output. There is potential you may get snagged on input. May need to fight with interrupt routing or some garbage. My untested UART input code

If you’d like 4 r5f cores outside of lockstep, I’d assume you should be able to make that the case using a DT overlay.

If you really want to use an RTOS, there is work-in-progress work with Zephyr BeagleBone AI-64 — Zephyr Project Documentation. Hopefully they can get IPC figured out soon…Check with people on discord. Add support yourself?

Hey Kevin

Thank you for your answer.

I’m currently using your code example, thank you it is very interesting!

Can you explain me more about the rpmsg application ?
How does it work ? And how to use it ? It is used to launch a function on the R5F from the Linux userland application, isn’t it ?

Is it possible to use UDMA on the R5F to achieve data from the UART controller to the SOC memory ? It would be great if it raises an interruption :slight_smile:

Thanks !
Valentin

I have not played with or looked into using DMA or UDMA. Can’t answer you on that.

The RPMSG code I currently have pushed is pretty bare, a mess, and sucky. It has Linux calling functions running on the R5 and taking return values. Basically a demonstration of two way messaging. Each side has RPMSG send and receive demonstrated and working.

You’ll want to throw away the logic I built on top, it is trash. Anyway, from basic send and receive, you can build on top whatever message protocol out there that supports 256byte messages. I believe the go to normal option it to implement OpenAMP on top, although I might be misunderstanding things…Ask Grok to help you out with figuring out what to do here…

Currently I am working on some custom protocol for my example app. I am not done, likely will not push until at least the end of the week. (struggling with some personal stuff rn)

Here’s the structure setup I am using


typedef enum {
    MESSAGE_UNKNOWN = 0,
    MESSAGE_REQUEST = 1,
    MESSAGE_RESPONSE = 2,
} MESSAGE_TAG;

typedef enum {
    FUNCTION_UNKNOWN = 0,
    FUNCTION_A = 1,    // Takes two ints, returns an int (on R5)
    FUNCTION_B = 2,    // Takes three floats, returns a float (on R5)

    // Linux functions
    FUNCTION_X = 3,    // Takes an int, returns a float (on Linux)
    FUNCTION_Y = 4,    // Takes a float, returns an int (on Linux)
} FUNCTION_TAG;

typedef struct {
    FUNCTION_TAG function_tag;
    union {
        // R5 functions
        struct {
            int a;
            int b;
        } function_a;
        struct {
            float a;
            float b;
            float c;
        } function_b;

        // linux functions
        struct {
            int param;
        } function_x;
        struct {
            float param;
        } function_y;
    } params;
} request_data_t;

typedef struct {
    FUNCTION_TAG function_tag;
    union {
        int result_function_a;
        float result_function_b;
        float result_function_x;
        int result_function_y;
    } result;
} response_data_t;

// typedef struct __attribute__((packed)) { // packing caused sized to not match between cores...
typedef struct {
    MESSAGE_TAG tag;
    uint32_t request_id;
    union {
        request_data_t request;
        response_data_t response;
    } data;
} MESSAGE;