This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM6442: Remoteproc Linux Debugging Questions

Part Number: AM6442
Other Parts Discussed in Thread: SYSCONFIG,

Hi,

I have a couple of questions regarding debugging remote cores via Linux.

I've read through the AM64x Academy documentation on this and I have a few questions.

  1. The documentation linked above says, "If the remote core binary was configured to provide a trace log, Linux can see the remote core’s debug log through sysfs." What does it mean for the remote core binary to be configured to provide a trace log? Is this something I need to set up in the resource table, or is there something I need to do in SysConfig?
  2. There are some SysConfig Debug Log options that are slightly unclear to me. More specifically, I am uncertain about the difference between the Enable Memory Log and Enable Shared Memory Log Writer options. Do I need both of these options enabled in order to write to shared memory, or are these options completely separate and writing to different shared memory locations? Are any of these options related to the trace log?
  3. I am trying to load firmware onto the r5f0_0 core. When doing this through CCS via Run->Load->Load Program, the code runs with no issues; however, when I run the same binary via remoteproc with echo start > /sys/class/remoteproc/remoteproc1/state, the code seems to fail almost immediately. Note that I have verified that remoteproc1 does correspond to the r5f0_0 core. I'm not sure where this is failing as I have not been able to get the shared memory log working, but I am interested to get input on why the code fails when uploading via remoteproc and not when uploading via CCS. I know this is a very vague question, but I am wondering if there are any known gotchas here; for instance, if I have the CCS Log option enabled in SysConfig, could Dpl_init be failing when it is unable to find a connected JTAG interface?

Thanks for your help,

Jared

  • Hello Jared,

    How to enable the trace log for Linux to look at? 

    This info is hiding in Multicore academy page "Add Linux IPC to the remote core project":
    https://dev.ti.com/tirex/explore/node?a=7qm9DIS__LATEST&node=A__Ac4gvmV7H7iX5x.qB.hWZw__AM64-ACADEMY__WI1KRXP__LATEST 

    It can also be helpful for debugging to go to “TI DRIVER PORTING LAYER” > Debug Log and enable “Enable Memory Log”

    Is the trace log enabled in SysConfig, or the resource table?

    The answer is actually "both". For more information, refer to Multicore academy page "Adding an empty resource table"
    https://dev.ti.com/tirex/explore/node?a=7qm9DIS__LATEST&node=A__AbHsVQIi8pUVEQOLKmXydQ__AM64-ACADEMY__WI1KRXP__LATEST

    Debug tips as you start by loading the R5F firmware from Linux? 

    There are many different things that could be going on, so I would need you to provide more debug information to give specific comments. However, here are some high level thoughts:

    1) I have never seen the trace log itself cause any issues (mostly tested with enabling Linux RPMsg and using the default generated resource table)

    2) Most of the issues I have seen that prevent R5F from running properly when initialized by Linux are documented in Multicore academy section "Modify the remote core application to be loaded by Linux"
    https://dev.ti.com/tirex/explore/node?a=7qm9DIS__LATEST&node=A__AScRgxl3hmonfFqU7DrFFw__AM64-ACADEMY__WI1KRXP__LATEST 

    3) If you are seeing any errors from the Linux terminal, please share those. Usually they are caused by the firmware not being in the location Linux expects, or by not including a resource table. For more information, refer to Linux academy section "Booting remote cores"
    https://dev.ti.com/tirex/explore/node?a=7qm9DIS__LATEST&node=A__AdAyuKWUWVV5j4wBc7C6XA__AM64-ACADEMY__WI1KRXP__LATEST

    4) You can use CCS to pinpoint exactly where the issue is happening. Especially if it is a resource conflict issue, you may run into a crash during System_init. I provide an example of how I do that debug in Multicore academy "Debug the remote core through CCS"
    https://dev.ti.com/tirex/explore/node?a=7qm9DIS__LATEST&node=A__AZVLTFgnCWyMV5cDwLf4gg__AM64-ACADEMY__WI1KRXP__LATEST

    Regards,

    Nick

  • For future readers, Jared came back and said he got everything working with the links in the previous response.

    Hello Jared,

    I have split off your question about AM263Px SBL size optimization into a separate e2e question, and sent it over to the AM263Px team:
    minimal SBL for the am263px

    Within the context of Linux loading a non-Linux core, you can strip out debug information and other unneeded data as documented in the AM64x multicore academy > 
    How to optimize remote core project memory
    https://dev.ti.com/tirex/explore/node?node=A__AeakdFP2wJ-rLsVTOacY7Q__AM64-ACADEMY__WI1KRXP__LATEST 

    However, I am not sure about optimizing binary sizes from the perspective of SBL boot on a non-Linux processor.

    Regards,

    Nick

  • Hey Nick,

    Thanks for creating the new thread, really appreciate your help!

    Thanks again,

    - Jared

  • Hello Jared,

    No problem, glad we were able to unblock the R5F debug so quickly! Feel free to create a new thread if any other questions come up.

    Regards,

    Nick

  • Hey Nick,

    Thought all was well, but I am actually running into some issues.

    First, I should have mentioned this earlier, but it seems like your patch for enabling trace is no longer required as sysconfig automatically adds the patch contents to 'generated/ti_drivers_config.c'.

    The issue that I am running into is that starting the r5f0-0 via remoteproc with:

    echo start > /sys/class/remoteproc/remoteproc1/state


    occasionally causes a SOC reset. There is no kernel panic, so I don't think this is an issue with the kernel; however, I am not really sure how to determine the root cause.

    In order to reproduce this:

    1. reboot Linux. Note that remoteproc automatically starts all remote cores as defined by DT and I have yet to see any failure during this stage
    2. stop r5f0-0 with `echo stop > /sys/class/remoteproc/remoteproc1/state`
    3. start r5f0-0 with `echo start > /sys/class/remoteproc/remoteproc1/state`. Note that sometimes this is actually successful; however, if I repeat steps 1 and 3, I can eventually reproduce the crash.

    Below are the outputs of the failed remoteproc command:

    ****** stop r5 core *******
    root@aec-am6442:~# echo stop > /sys/class/remoteproc/remoteproc1/state
    [  328.830897] remoteproc remoteproc1: stopped remote processor 78000000.r5f
    
    ****** attempt to restart r5 core *****
    root@aec-am6442:~# strace echo start > /sys/class/remoteproc/remoteproc1/state
    execve("/usr/bin/echo", ["echo", "start"], 0xffffc25862e8 /* 17 vars */) = 0
    brk(NULL)                               = 0xaaaaed[  332.550696] remoteproc remoteproc1: powering up 78000000.r5f
    fc8000
    faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENO[  332.560443] remoteproc remoteproc1: Booting fw image am64-main-r5f0_0-fw, size 403572
    ENT (No such file or directory)
    openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=6699, ...}) = 0
    mmap(NULL, 6699, PROT_READ, MAP_PRIVATE, 3, 0) = 0xffff8cf06000
    close(3)                                = 0
    openat(AT_FDCWD, "/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\0\207\2\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=1650968, ...}) = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff8cf04000
    mmap(NULL, 1826688, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_DENYWRITE, -1, 0) = 0xffff8cd10000
    mmap(0xffff8cd10000, 1761152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0xffff8cd10000
    munmap(0xffff8cebe000, 65408)           = 0
    mprotect(0xffff8ce9b000, 73728, PROT_NONE) = 0
    mmap(0xffff8cead000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18d000) = 0xffff8cead000
    mmap(0xffff8ceb2000, 49024, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffff8ceb2000
    close(3)                                = 0
    set_tid_address(0xffff8cf04e50)         = 399
    set_robust_list(0xffff8cf04e60, 24)     = 0
    rseq(0xffff8cf054a0, 0x20, 0, 0xd428bc00) = 0
    mprotect(0xffff8cead000, 12288, PROT_READ) = 0
    mprotect(0xaaaac570f000, 4096, PROT_READ) = 0
    mprotect(0xffff8cf0c000, 8192, PROT_READ) = 0
    prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
    munmap(0xffff8cf06000, 6699)            = 0
    getrandom("\xfc\xdc\x8d\x33\x89\x05\xb6\x84", 8, GRND_NONBLOCK) = 8
    brk(NULL)                               = 0xaaaaedfc8000
    brk(0xaaaaedfe9000)                     = 0xaaaaedfe9000
    fstat(1, {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
    write(1, "start\n", 6
    
    ***** SOC reset occured, rebooting now *****
    U-Boot SPL 2025.01-00054-g6980061fa875-dirty (Feb 12 2025 - 05:47:04 +0000)
    

    I do not have graceful shutdowns implemented as outlined in this documentation, and my best guess is that this is causing the r5 to be in a bad state after shutdown, which then leads to a crash when I attempt to restart the core; however, I am unsure how to verify this.

    Questions for you:

    1. Do you have any recommendations on how to debug this issue?
    2. Would you agree that this is likely caused by the r5 being in a bad state after shutdown?
    3. Do you have any other words of wisdom regarding what could be causing this?

    Thanks for all your help,

    - Jared

  • Update:

    I just saw this thread regarding similar issue.

    I am running kernel version 6.12.8; however, I am building the kernel via Yocto and utilizing Phytec's kernel port which is based off of TI's port. I am using SDK version 11.01.00.17. Do you know if graceful shutdown is supported using these versions?

    Thanks,

    - Jared

  • Hello Jared,

    I do not recall seeing this exact behavior before.

    I am surprised that the Linux remoteproc driver is shutting off the remote core if you have not enabled graceful shutdown in your R5F firmware. If you are using TI's version of the remoteproc driver, I would expect that the Linux driver should send a shutdown notification to the R5F, wait 5 seconds, and then timeout and abort the shutdown since the R5F does not respond.

    Did you modify the driver so that there is no longer a timeout?

    I am not sure if the graceful shutdown code has been upstreamed or not, so that would be another thing to check if Phytec actually has the same driver code that you see on ti-linux-6.12.y branch,  k3_r5_suspend function:
    https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/remoteproc/ti_k3_r5_remoteproc.c?h=ti-linux-6.12.y-cicd#n507 

    Regards,

    Nick

  • Hey Nick,

    I put this on the backburner as I was thinking it would only effect development; however, I realized that we are going to need the ability to change the R5 firmware in production.

    For some background here, when the am6442 first boots, I would like to load some firmware onto r5fss0-0, this firmware will assist in booting a connected am263p by streaming an MCELF over FSI. Once this process finishes, I would like to load new firmware onto the r5fss0-0 core.

    My issue is that I am still seeing the issue stated above where starting firmware via rproc occasionally causes an SOC reset. I have not implemented graceful shutdown in my firmware and Phytec's remoteproc source is pretty much identical to TI's (diff attached).

    The am6442 multicore academy documentation states:

    If the remote core is powered off during Linux runtime without warning the DM core, then the remote core is not able to tell the DM core to release its peripherals. When the remote core requests its peripherals after being rebooted, the DM core will refuse the request, because the DM core thinks that the peripherals are still in use. At that point, the remote core typically stalls, and the entire processor needs to be rebooted.

    My guess is that the R5 core hangs due to the reasons stated in the documentation and then a watchdog reboot occurs due to the core hanging. I'm not sure what the best approach is for confirming that this is in fact what is occurring, but there does seem to be a significant delay (a few seconds) between issuing the start command and the SOC rebooting. 

    QUESTIONS:

    1. You mentioned that the expected behavior for shutdown is that Linux will send a shutdown message via rproc, the R5 core will not respond, and therefore the shutdown request will abort. This is not the behavior that I am seeing. When I issue a shutdown command via `echo stop > /sys/class/remoteproc/remoteproc<n>/state` I get the following:

                     [ 2732.443757] remoteproc remoteproc1: stopped remote processor 78000000.r5f

      There is not a noticeable delay, and it seems like the core is successfully shutdown, at least /sys/class/remoteproc/remoteproc<n>/state indicates this. Is this expected behavior or not?

    2. Do have any recommendations on how to verify whether or not the SOC reset is caused by a watchdog reset? Do you have any other ideas what would be causing this behavior?

    Thanks for all your help,


    - Jared

    --- _ti_k3_r5_remoteproc.c	2025-12-17 13:39:01.235512803 -0800
    +++ drivers/remoteproc/ti_k3_r5_remoteproc.c	2025-12-17 13:38:56.939514816 -0800
    @@ -489,6 +489,7 @@
     	struct k3_r5_rproc *kproc = rproc->priv;
     	struct mbox_client *client = &kproc->client;
     	struct device *dev = kproc->dev;
    +	int ret;
     
     	client->dev = dev;
     	client->tx_done = NULL;
    @@ -501,6 +502,20 @@
     		return dev_err_probe(dev, PTR_ERR(kproc->mbox),
     				     "mbox_request_channel failed\n");
     
    +	/*
    +	 * Ping the remote processor, this is only for sanity-sake for now;
    +	 * there is no functional effect whatsoever.
    +	 *
    +	 * Note that the reply will _not_ arrive immediately: this message
    +	 * will wait in the mailbox fifo until the remote processor is booted.
    +	 */
    +	ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
    +	if (ret < 0) {
    +		dev_err(dev, "mbox_send_message failed: %d\n", ret);
    +		mbox_free_channel(kproc->mbox);
    +		return ret;
    +	}
    +
     	return 0;
     }
     
    @@ -1518,10 +1533,6 @@
     			goto out;
     		}
     
    -		ret = dma_coerce_mask_and_coherent(&rproc->dev, DMA_BIT_MASK(48));
    -		if (ret)
    -			dev_warn(dev, "Failed to set DMA mask (%d)\n", ret);
    -
     		/* K3 R5s have a Region Address Translator (RAT) but no MMU */
     		rproc->has_iommu = false;
     		/* error recovery is not supported at present */
    

    --- _ti_k3_r5_remoteproc.c	2025-12-17 13:39:01.235512803 -0800
    +++ drivers/remoteproc/ti_k3_r5_remoteproc.c	2025-12-17 13:38:56.939514816 -0800
    @@ -489,6 +489,7 @@
     	struct k3_r5_rproc *kproc = rproc->priv;
     	struct mbox_client *client = &kproc->client;
     	struct device *dev = kproc->dev;
    +	int ret;
     
     	client->dev = dev;
     	client->tx_done = NULL;
    @@ -501,6 +502,20 @@
     		return dev_err_probe(dev, PTR_ERR(kproc->mbox),
     				     "mbox_request_channel failed\n");
     
    +	/*
    +	 * Ping the remote processor, this is only for sanity-sake for now;
    +	 * there is no functional effect whatsoever.
    +	 *
    +	 * Note that the reply will _not_ arrive immediately: this message
    +	 * will wait in the mailbox fifo until the remote processor is booted.
    +	 */
    +	ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
    +	if (ret < 0) {
    +		dev_err(dev, "mbox_send_message failed: %d\n", ret);
    +		mbox_free_channel(kproc->mbox);
    +		return ret;
    +	}
    +
     	return 0;
     }
     
    @@ -1518,10 +1533,6 @@
     			goto out;
     		}
     
    -		ret = dma_coerce_mask_and_coherent(&rproc->dev, DMA_BIT_MASK(48));
    -		if (ret)
    -			dev_warn(dev, "Failed to set DMA mask (%d)\n", ret);
    -
     		/* K3 R5s have a Region Address Translator (RAT) but no MMU */
     		rproc->has_iommu = false;
     		/* error recovery is not supported at present */
    

  • Edited Dec 23 2025

    Hello Jared,

    Graceful shutdown from the Linux side:

    TI's graceful shutdown code has not been upstreamed at this point. If you want to shut down and restart the R5F during runtime, longer term I would suggest adding support for graceful shutdown to the Linux driver.

    It actually looks like someone from bootlin is looking into upstreaming graceful shutdown. You may be able to get ideas from that draft:
    https://lkml.org/lkml/2025/11/27/27

    Beleswar is one of our TI developers.

    Short term: make sure that the first R5F firmware is releasing all resources before Linux would shut it down 

    If you know that the first R5F firmware will always get shut down, in the short term you don't have to figure out the Linux graceful shutdown patches. I would set up a handshake with Linux to indicate that you are done (e.g., send an RPMsg if you already have that configured between R5F and Linux), and then immediately put the R5F into a "known good state".

    If your issue goes away, then you know it was caused by the R5F not being in a good state before getting shut down.

    The AM64x repo has lagged behind the AM62x repo with regards to the RPMsg / graceful shutdown example, so please refer to the AM62x version of the example for the process to release all resources and go into WFI.

    AM64x repo project is herehttps://github.com/TexasInstruments/mcupsdk-core/blob/next/examples/drivers/ipc/ipc_rpmsg_echo_linux/ipc_rpmsg_echo.c 

    AM62x repo project is here: https://github.com/TexasInstruments/mcupsdk-core-k3/blob/k3_main/examples/drivers/ipc/ipc_rpmsg_echo_linux/ipc_rpmsg_echo.c 

    Here is an example from another customer who just got graceful shutdown working with their AM64x R5F project:
    AM64X-ADVANCE-SW: Graceful shutdown implementation in R core using Interrupt 

    Can we view reset reason?

    Yes, you can view the RST_SRC register to see the cause of a warm reset or a MAIN domain power on reset. Search the TRM for CTRLMMR_RST_SRC, you can read with devmem2 if that is enabled in your filesystem.

    Regards,

    Nick

  • Hey Nick,

    Thanks for your reply.

    I am trying to implement graceful shutdown with no luck thus far. I looked at 'ipc_rpmsg_echo.c', which seems to be overkill for just implementing graceful shutdown. I ended up with the following:


    void ipc_rp_mbox_callback(uint32_t remoteCoreId, uint16_t clientId, uint32_t msgValue, int32_t crcStatus, void *args)
    {
        if (clientId == IPC_NOTIFY_CLIENT_ID_RP_MBOX && msgValue == IPC_NOTIFY_RP_MBOX_SHUTDOWN)
        {
            IpcNotify_sendMsg(gShutdownRemotecoreID, IPC_NOTIFY_CLIENT_ID_RP_MBOX, IPC_NOTIFY_RP_MBOX_SHUTDOWN_ACK, 1u);
            FSI_txDeinit(CONFIG_FSI_TX0_BASE_ADDR);
            FSI_rxDeinit(CONFIG_FSI_RX0_BASE_ADDR);
            Board_driversClose();
            Drivers_close();
            Board_deinit();
            System_deinit();
            HwiP_disable();
            __asm__ __volatile__ ("wfi"   "\n\t": : : "memory");
        }
    }
    
    void *fsi_transfer_mcelf_main(void *args)
    {
        Float32 transferTime;
        uint64_t startTime;
        uint64_t endTime;
        uint32_t retries = 0U;
        int32_t status;
        volatile uint8_t loop = 1U;
    
        /* Initialize drivers */
        Drivers_open();
        Board_driversOpen();
    
        while(loop);
    
        /* Initialize RPMessage and register shutdown callback for graceful shutdown */
        RPMessage_waitForLinuxReady(SystemP_WAIT_FOREVER);
        IpcNotify_registerClient(IPC_NOTIFY_CLIENT_ID_RP_MBOX, &ipc_rp_mbox_callback, NULL);


    Do you know of any reason not to implement the graceful shutdown logic within the interrupt context like I have above?

    Also, when debugging this, I don't seem to be receiving the shutdown message from rproc, at least I am not hitting the breakpoint I've set within the callback function. Any thoughts on where I am going wrong here? I may have an incorrect SysConfig or something (SysConfig script attached).

    Thanks for your help,

    Jared

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "AM64x" --part "Default" --package "ALV" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM64x@11.01.00"
     * @v2CliArgs --device "AM6442" --package "FCBGA (ALV)" --variant "AM6442-D" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM64x@11.01.00"
     * @versions {"tool":"1.25.0+4268"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const fsi_rx          = scripting.addModule("/drivers/fsi_rx/fsi_rx", {}, false);
    const fsi_rx1         = fsi_rx.addInstance();
    const fsi_tx          = scripting.addModule("/drivers/fsi_tx/fsi_tx", {}, false);
    const fsi_tx1         = fsi_tx.addInstance();
    const ipc             = scripting.addModule("/drivers/ipc/ipc");
    const debug_log       = scripting.addModule("/kernel/dpl/debug_log");
    const dpl_cfg         = scripting.addModule("/kernel/dpl/dpl_cfg");
    const mpu_armv7       = scripting.addModule("/kernel/dpl/mpu_armv7", {}, false);
    const mpu_armv71      = mpu_armv7.addInstance();
    const mpu_armv72      = mpu_armv7.addInstance();
    const mpu_armv73      = mpu_armv7.addInstance();
    const mpu_armv74      = mpu_armv7.addInstance();
    const mpu_armv75      = mpu_armv7.addInstance();
    const mpu_armv76      = mpu_armv7.addInstance();
    const default_linker  = scripting.addModule("/memory_configurator/default_linker", {}, false);
    const default_linker1 = default_linker.addInstance();
    const general         = scripting.addModule("/memory_configurator/general", {}, false);
    const general1        = general.addInstance();
    const region          = scripting.addModule("/memory_configurator/region", {}, false);
    const region1         = region.addInstance();
    const section         = scripting.addModule("/memory_configurator/section", {}, false);
    const section1        = section.addInstance();
    const section2        = section.addInstance();
    const section3        = section.addInstance();
    const section4        = section.addInstance();
    const section5        = section.addInstance();
    const section6        = section.addInstance();
    const section7        = section.addInstance();
    const section8        = section.addInstance();
    const section9        = section.addInstance();
    const section10       = section.addInstance();
    const section11       = section.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    fsi_rx1.$name              = "CONFIG_FSI_RX0";
    fsi_rx1.FSI_RX.$assign     = "FSI_RX0";
    fsi_rx1.FSI_RX.CLK.$assign = "GPMC0_AD8";
    fsi_rx1.FSI_RX.D0.$assign  = "GPMC0_AD9";
    fsi_rx1.FSI_RX.D1.$assign  = "GPMC0_AD10";
    fsi_rx1.child.$name        = "drivers_fsi_rx_v0_fsi_rx_v0_template0";
    
    fsi_tx1.$name              = "CONFIG_FSI_TX0";
    fsi_tx1.FSI_TX.$assign     = "FSI_TX0";
    fsi_tx1.FSI_TX.CLK.$assign = "GPMC0_BE1n";
    fsi_tx1.FSI_TX.D0.$assign  = "GPMC0_AD14";
    fsi_tx1.FSI_TX.D1.$assign  = "GPMC0_AD15";
    fsi_tx1.child.$name        = "drivers_fsi_tx_v0_fsi_tx_v0_template0";
    
    ipc.enableLinuxIpc = true;
    ipc.r5fss1_1       = "NONE";
    ipc.r5fss1_0       = "NONE";
    ipc.r5fss0_1       = "NONE";
    ipc.m4fss0_0       = "NONE";
    
    debug_log.enableLogZoneInfo = true;
    debug_log.enableMemLog      = true;
    debug_log.enableCssLog      = false;
    
    mpu_armv71.$name             = "CONFIG_MPU_REGION0";
    mpu_armv71.size              = 31;
    mpu_armv71.attributes        = "Device";
    mpu_armv71.accessPermissions = "Supervisor RD+WR, User RD";
    mpu_armv71.allowExecute      = false;
    
    mpu_armv72.$name             = "CONFIG_MPU_REGION1";
    mpu_armv72.size              = 15;
    mpu_armv72.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv73.$name             = "CONFIG_MPU_REGION2";
    mpu_armv73.baseAddr          = 0x41010000;
    mpu_armv73.size              = 15;
    mpu_armv73.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv74.$name             = "CONFIG_MPU_REGION3";
    mpu_armv74.baseAddr          = 0x70000000;
    mpu_armv74.size              = 21;
    mpu_armv74.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv75.$name             = "CONFIG_MPU_REGION4";
    mpu_armv75.baseAddr          = 0x60000000;
    mpu_armv75.size              = 28;
    mpu_armv75.accessPermissions = "Supervisor RD, User RD";
    
    mpu_armv76.$name    = "CONFIG_MPU_REGION5";
    mpu_armv76.baseAddr = 0x80000000;
    mpu_armv76.size     = 31;
    
    default_linker1.$name = "memory_configurator_default_linker0";
    
    general1.$name        = "CONFIG_GENERAL0";
    general1.linker.$name = "TIARMCLANG0";
    
    region1.$name                                = "MEMORY_REGION_CONFIGURATION0";
    region1.memory_region.create(11);
    region1.memory_region[0].type                = "TCMA_R5F";
    region1.memory_region[0].$name               = "R5F_VECS";
    region1.memory_region[0].size                = 0x40;
    region1.memory_region[0].auto                = false;
    region1.memory_region[1].type                = "TCMA_R5F";
    region1.memory_region[1].$name               = "R5F_TCMA";
    region1.memory_region[1].size                = 0x7FC0;
    region1.memory_region[2].type                = "TCMB_R5F";
    region1.memory_region[2].$name               = "R5F_TCMB0";
    region1.memory_region[2].size                = 0x8000;
    region1.memory_region[3].$name               = "MSRAM";
    region1.memory_region[3].auto                = false;
    region1.memory_region[3].manualStartAddress  = 0x70040000;
    region1.memory_region[3].size                = 0x60000;
    region1.memory_region[4].type                = "FLASH";
    region1.memory_region[4].$name               = "FLASH";
    region1.memory_region[4].auto                = false;
    region1.memory_region[4].manualStartAddress  = 0x60100000;
    region1.memory_region[4].size                = 0x80000;
    region1.memory_region[5].auto                = false;
    region1.memory_region[5].size                = 0x100000;
    region1.memory_region[5].type                = "DDR_ALL";
    region1.memory_region[5].$name               = "LINUX_IPC_SHM";
    region1.memory_region[5].manualStartAddress  = 0xA0000000;
    region1.memory_region[6].type                = "DDR_ALL";
    region1.memory_region[6].$name               = "RTBL_SHM";
    region1.memory_region[6].auto                = false;
    region1.memory_region[6].manualStartAddress  = 0xA0100000;
    region1.memory_region[6].size                = 0x1000;
    region1.memory_region[7].type                = "DDR_ALL";
    region1.memory_region[7].$name               = "TRACE_LOG_SHM";
    region1.memory_region[7].auto                = false;
    region1.memory_region[7].manualStartAddress  = 0xA0101000;
    region1.memory_region[7].size                = 0x10000;
    region1.memory_region[8].type                = "DDR_ALL";
    region1.memory_region[8].$name               = "DSP_IMG_SHM";
    region1.memory_region[8].auto                = false;
    region1.memory_region[8].manualStartAddress  = 0xA0111000;
    region1.memory_region[8].size                = 0x500000;
    region1.memory_region[9].type                = "DDR_ALL";
    region1.memory_region[9].$name               = "DDR";
    region1.memory_region[9].auto                = false;
    region1.memory_region[9].size                = 0xE9F000;
    region1.memory_region[9].manualStartAddress  = 0xA0611000;
    region1.memory_region[10].type               = "DDR_ALL";
    region1.memory_region[10].$name              = "IPC_SHM";
    region1.memory_region[10].auto               = false;
    region1.memory_region[10].manualStartAddress = 0xA5004000;
    region1.memory_region[10].size               = 0xC000;
    
    section1.$name                        = "Vector Table";
    section1.load_memory                  = "R5F_VECS";
    section1.group                        = false;
    section1.output_section.create(1);
    section1.output_section[0].$name      = ".vectors";
    section1.output_section[0].palignment = true;
    
    section2.$name                        = "Text Segments";
    section2.load_memory                  = "MSRAM";
    section2.output_section.create(5);
    section2.output_section[0].$name      = ".text.hwi";
    section2.output_section[0].palignment = true;
    section2.output_section[1].$name      = ".text.cache";
    section2.output_section[1].palignment = true;
    section2.output_section[2].$name      = ".text.mpu";
    section2.output_section[2].palignment = true;
    section2.output_section[3].$name      = ".text.boot";
    section2.output_section[3].palignment = true;
    section2.output_section[4].$name      = ".text:abort";
    section2.output_section[4].palignment = true;
    
    section3.$name                        = "Code and Read-Only Data";
    section3.load_memory                  = "DDR";
    section3.output_section.create(2);
    section3.output_section[0].$name      = ".text";
    section3.output_section[0].palignment = true;
    section3.output_section[1].$name      = ".rodata";
    section3.output_section[1].palignment = true;
    
    section4.$name                        = "Data Segment";
    section4.load_memory                  = "DDR";
    section4.output_section.create(1);
    section4.output_section[0].$name      = ".data";
    section4.output_section[0].palignment = true;
    
    section5.$name                                   = "Memory Segments";
    section5.load_memory                             = "DDR";
    section5.output_section.create(3);
    section5.output_section[0].$name                 = ".bss";
    section5.output_section[0].palignment            = true;
    section5.output_section[0].output_sections_start = "__BSS_START";
    section5.output_section[0].output_sections_end   = "__BSS_END";
    section5.output_section[1].$name                 = ".sysmem";
    section5.output_section[1].palignment            = true;
    section5.output_section[2].$name                 = ".stack";
    section5.output_section[2].palignment            = true;
    
    section6.$name                                    = "Stack Segments";
    section6.load_memory                              = "DDR";
    section6.output_section.create(5);
    section6.output_section[0].$name                  = ".irqstack";
    section6.output_section[0].output_sections_start  = "__IRQ_STACK_START";
    section6.output_section[0].output_sections_end    = "__IRQ_STACK_END";
    section6.output_section[0].input_section.create(1);
    section6.output_section[0].input_section[0].$name = ". = . + __IRQ_STACK_SIZE;";
    section6.output_section[1].$name                  = ".fiqstack";
    section6.output_section[1].output_sections_start  = "__FIQ_STACK_START";
    section6.output_section[1].output_sections_end    = "__FIQ_STACK_END";
    section6.output_section[1].input_section.create(1);
    section6.output_section[1].input_section[0].$name = ". = . + __FIQ_STACK_SIZE;";
    section6.output_section[2].$name                  = ".svcstack";
    section6.output_section[2].output_sections_start  = "__SVC_STACK_START";
    section6.output_section[2].output_sections_end    = "__SVC_STACK_END";
    section6.output_section[2].input_section.create(1);
    section6.output_section[2].input_section[0].$name = ". = . + __SVC_STACK_SIZE;";
    section6.output_section[3].$name                  = ".abortstack";
    section6.output_section[3].output_sections_start  = "__ABORT_STACK_START";
    section6.output_section[3].output_sections_end    = "__ABORT_STACK_END";
    section6.output_section[3].input_section.create(1);
    section6.output_section[3].input_section[0].$name = ". = . + __ABORT_STACK_SIZE;";
    section6.output_section[4].$name                  = ".undefinedstack";
    section6.output_section[4].output_sections_start  = "__UNDEFINED_STACK_START";
    section6.output_section[4].output_sections_end    = "__UNDEFINED_STACK_END";
    section6.output_section[4].input_section.create(1);
    section6.output_section[4].input_section[0].$name = ". = . + __UNDEFINED_STACK_SIZE;";
    
    section7.$name                        = "Initialization and Exception Handling";
    section7.load_memory                  = "DDR";
    section7.output_section.create(3);
    section7.output_section[0].$name      = ".ARM.exidx";
    section7.output_section[0].palignment = true;
    section7.output_section[1].$name      = ".init_array";
    section7.output_section[1].palignment = true;
    section7.output_section[2].$name      = ".fini_array";
    section7.output_section[2].palignment = true;
    
    section8.type                        = "NOLOAD";
    section8.$name                       = "Trace Log Shared Memory";
    section8.load_memory                 = "TRACE_LOG_SHM";
    section8.output_section.create(1);
    section8.output_section[0].alignment = 0;
    section8.output_section[0].$name     = ".bss.debug_mem_trace_buf";
    
    section9.$name                        = "Resource Table";
    section9.load_memory                  = "RTBL_SHM";
    section9.output_section.create(1);
    section9.output_section[0].palignment = true;
    section9.output_section[0].alignment  = 4096;
    section9.output_section[0].$name      = ".resource_table";
    
    section10.$name                        = "DSP Firmware";
    section10.load_memory                  = "DSP_IMG_SHM";
    section10.output_section.create(1);
    section10.output_section[0].palignment = true;
    section10.output_section[0].$name      = ".rodata.dsp.firmware";
    
    section11.type                    = "NOLOAD";
    section11.$name                   = "IPC Shared Memory";
    section11.group                   = false;
    section11.load_memory             = "IPC_SHM";
    section11.output_section.create(1);
    section11.output_section[0].$name = ".bss.ipc_vring_mem";
    

  • Hello Jared,

    Ran out of time today. Will try to give a response on Friday. If I don't reply on Friday, please ping the thread so I can try to give a response before going on vacation.

    Regards,

    Nick

  • Hello Jared,

    That is fair feedback. The ipc_rpmsg_echo_linux project is our "catch all" example for MCU+ & Linux coexisting on the processor, so we cram a lot of code into a single project when it would probably be easier to have simpler examples, one for each concept.

    error, wrong link in previous response 

    It looks like I linked to the AM64x version of the ipc_rpmsg_echo_linux project, when I meant to link to the AM62x version of the ipc_rpmsg_echo_linux project. I apologize if this caused any confusion.

    Next steps that I would look at

    It might be easier to test this one step at a time. First, I would test to see if this is truly an issue related to getting the R5F core into a "known good" state before it is powered off. Don't wait for a mailbox message from Linux to run that code.

    Based on your description of the usecase, I would add the discussed code [HERE]

    this [r5fss0-0] firmware will assist in booting a connected am263p by streaming an MCELF over FSI. Once this process finishes, [PUT R5F INTO KNOWN GOOD STATE]. I would like to load new firmware onto the r5fss0-0 core

    You can add some simple print statements before you put the code into a known good state, and then you'll be able to check the Linux trace log as discussed in the Linux academy to make sure the R5F actually goes to the known good state before you shut off the core.

    In general, the code from your callback function looks like what I would expect for putting the core into a known good state. Some notes:

    * I assume you do not create a gIpcAckReplyMsgObject, so you don't need to worry about calling RPMessage_unblock/destruct with that. If you have a gIpcRecvMsgObject, it may be good to call RPMessage_unblock

    * vTaskDelete not needed if your application is only one task, since this is called when the main function returns to main.c

    * I do not see Board_deinit called in the IPC examples, not sure if this is needed or not

    * I have not looked at the FSI code, I'll assume you are deinitializing properly

    FYI, I will be on vacation until the middle of next week.

    Regards,

    Nick