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.

[参考译文] AM620-Q1:IPC 从仅 MCU 模式恢复时崩溃

Guru**** 2418880 points
Other Parts Discussed in Thread: SK-AM62-LP

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1532839/am620-q1-ipc-crash-in-resume-from-mcu-only-mode

主题中讨论的其他器件:SK-AM62-LP

[从 https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1529704/am620-q1-failed-to-use-mcu-only-mode]继续对话

你好,  Gibbs、

我们已经解决了 MCU 无法在仅模式下控制 IO 的问题。

接下来、请优先解决 MCU 唤醒 soc 并导致 IPC 崩溃和自动重启的问题

谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Walter、

    我们需要有关您正在测试的内容的更多信息。 以下是我目前所了解到的详细信息:

    Anshu 告诉我、您使用此 Linux 脚本运行测试:

    while true; do echo mem > /sys/power/state; done;

    根据该输入、我假设您显示的终端输出分成几个唤醒/暂停周期、如下所示:

    我们可以从输出“fifo 1 有意外的未读消息“验证 M4F 是在上图中的#2 期间未读取邮箱消息的用户(即,不是 Linux)。

    如果有人想要仔细检查我们如何验证“fifo 1“是什么意思的思考过程,我将附加相关代码片段。

    // from devicetree files
    // FIFO 1 is used for transmitting signals from Linux to M4F
    // mbox-m4-0 > ti,mbox-tx = <1 0 0>;
    
            mailbox0_cluster0: mailbox@29000000 {
                    compatible = "ti,am64-mailbox";
                    reg = <0x00 0x29000000 0x00 0x200>;
                    interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
                                 <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
                    #mbox-cells = <1>;
                    ti,mbox-num-users = <4>;
                    ti,mbox-num-fifos = <16>;
            };
    
    &mailbox0_cluster0 {
            mbox_m4_0: mbox-m4-0 {
                    ti,mbox-rx = <0 0 0>;
                    ti,mbox-tx = <1 0 0>;
            };
            mbox_r5_0: mbox-r5-0 {
                    ti,mbox-rx = <2 0 0>;
                    ti,mbox-tx = <3 0 0>;
            };
    };
    
    // from Linux driver
    // fifo %d refers to the actual hardware offset
    // i.e., 100% of the time, fifo 1 = the 2nd hardware fifo instance
    
    #define MAILBOX_MSGSTATUS(m)            (0x0c0 + 4 * (m))
    
    #ifdef CONFIG_PM_SLEEP
    static int omap_mbox_suspend(struct device *dev)
    {
            struct omap_mbox_device *mdev = dev_get_drvdata(dev);
            u32 usr, fifo, reg;
    
            if (pm_runtime_status_suspended(dev))
                    return 0;
    
            for (fifo = 0; fifo < mdev->num_fifos; fifo++) {
                    if (mbox_read_reg(mdev, MAILBOX_MSGSTATUS(fifo))) {
                            dev_err(mdev->dev, "fifo %d has unexpected unread messages\n",
                                    fifo);
                            return -EBUSY;
                    }
            }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请以粗体回答问题。  

    根据 7897 秒的终端时间戳、我假设您在遇到错误之前成功进入和退出了许多低功耗模式。

    问题 1:在遇到问题之前、您是否成功执行了多次低功耗模式循环?

    一个潜在的问题是 Linux 和 M4F 内核之间可能存在竞争条件。

    从 M4F 接收 echo_reply 邮箱、并开始下一次暂停之间只有 3 毫秒。 可能在 M4F 完成状态 从“低功耗模式“转换回“系统运行“之前、Linux 正在向 M4F 发送下一个低功耗模式信号、这会导致问题。

    测试 1:在 Linux 测试脚本中添加短延迟  

    如果 Linux 在启动下一个低功耗模式之前等待半秒或一秒、会发生什么情况? 崩溃行为是否消失?

    如果是,那么你有一个比赛条件。

    问题 2:您正在使用什么唤醒源进行这些测试?   如何触发 M4F 以唤醒系统?

    以下行告知我们 Linux 正在被 M4F 内核唤醒:
    TI_sci _resume:唤醒源:0x90

    有关更多信息、请参阅

    https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/10_01_10_04/exports/docs/linux/wakeup/IPC/pm_wakeup_sources.html#基于 Foundational_Components Power_Management 的唤醒


    和  

    https://downloads.ti.com/tisci/esd/latest/2_tisci_msgs/pm/lpm.html#tisci-msg-lpm-wake-reason

    Anshu 提到你已经尝试了一堆不同的唤醒源。 那么、您是否在将 UART 终端连接到 M4F 内核? 你在用别的东西吗? 请说明哪些唤醒源用于测试目的、哪些用于最终产品。

    问题 3:您是否使用了未修改的 ipc_rpmsg_echo_linux 示例? 如果您使用的是自定义代码,请让 Gibbs 与我们离线分享该自定义代码  

    如果您进行了大量代码更改、M4F 也可能在某个位置崩溃。 如果您仍在 M4F 上运行 IPC_RPMsg 回波测试代码、则可以使用 IPC_Echo 测试来查看 M4F 在低功耗模式转换失败后是否仍然能够响应:
    https://dev.ti.com/tirex/explore/node?node=A__AXINfJJ0T8V7CR5pTK41ww__AM62-ACADEMY__uiYMDcq__LATEST

    此致、

    Nick

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    问题 4:如果您使用自定义 M4F 代码、是否在 DDR 中存储了任何程序数据?  

    请让 Gibbs 离线与我们共享 linker.cmd 文件。

    在仅 MCU 低功耗模式下、无法访问 DDR。

    即使在 Linux 运行期间、M4F 没有任何缓存。 因此、对 DDR 的访问速度会非常慢。 这也可能会影响 Linux 和 M4F 之间的竞争条件。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Nick

    感谢您的建议、

    首先简单更新状态。

    我认为客户想要对 LPM(仅 MCU 模式)唤醒循环进行“压力测试“、所以他们设计了支出、目标是:  

    (1) 当 AM62 进入 LPM 并通过长时间测试从 LPM 循环唤醒时、是否会导致任何软件崩溃?

    (2) 当 AM62“要执行“LPM 过程时、是否导致了任何软件崩溃、但也同时收到唤醒事件?

    (3) 当 AM62“从 LPM 过程唤醒“但同时获得“睡眠“事件时、是否会导致任何软件崩溃?

    基本上、它们基于我们用于该测试的 IPC_RPMSG_ECHO_Linux 示例代码。

    文件作为附件。

    e2e.ti.com/.../ipc_5F00_rpmsg_5F00_echo_5F00_linux_5F00_am62x_2D00_sk_2D00_lp_5F00_m4fss0_2D00_0_5F00_freertos_5F00_ti_2D00_arm_2D00_clang_2D00_auto_5F00_timer.7z

    密钥代码修改

    static void lpm_mcu_wait_for_uart()
    {
        UART_Transaction trans;
        uint8_t uartData;
        int32_t status;
        uint32_t cnt = 0U;
        static uint32_t cnt1 = 0U;
        static uint8_t WakeFlag = 0U;
    
        UART_Transaction_init(&trans);
    
        /* Read 1 byte */
        trans.buf   = &uartData;
        trans.count = 1U;
    
        DebugP_memLogWriterPause();
    
        gNumBytesRead = 0u;
    
    	//DebugP_log(" mcu is running !\r\n mcu is running\r\n mcu is running\r\n mcu is running\r\n");
    
    	vTaskDelay(1000);
    	SOC_triggerMcuLpmWakeup();
    	SemaphoreP_pend(&gLpmResumeSem, SystemP_WAIT_FOREVER);
    	cnt1++;
    	DebugP_log("wake soc success,cnt = %u\r\n",cnt1);
    #if 0
    
        while(1)
        {
        	/*
    		if(cnt < 0x7FFFF)
            {
                cnt++;
            }
    		else
    		{
    			cnt1++;
    			DebugP_log("cnt = %u\r\n",cnt1);
    			cnt = 0U;
    			if (cnt1 == 5)
    			{
    				cnt1 = 0U;
    				SOC_triggerMcuLpmWakeup();
    				SemaphoreP_pend(&gLpmResumeSem, SystemP_WAIT_FOREVER);
    				break;
    			}
    		}
    		*/
        	// mcu透过api唤醒soc code
    		/*
            if(cnt < 0x7FFFFF)
            {
                cnt++;
            }
    		else
    		{
    			SOC_triggerMcuLpmWakeup();
    			SemaphoreP_pend(&gLpmResumeSem, SystemP_WAIT_FOREVER);
    			cnt1++;
    			DebugP_log("wake soc success,cnt = %u\r\n",cnt1);
    			break;
    		}
    		*/
        }
    
    
        /* Wait for any key to be pressed */
        status = UART_read(gUartHandle[CONFIG_UART0], &trans);
        DebugP_assert(status == SystemP_SUCCESS);
    
        while (gNumBytesRead == 0u && gbSuspended == 1u)
        {
        }
    
        if (gNumBytesRead != 0)
        {
            DebugP_log("[IPC RPMSG ECHO] Key pressed. Notifying DM to wakeup main domain\r\n");
            SOC_triggerMcuLpmWakeup();
            /* Wait for resuming the main domain */
            SemaphoreP_pend(&gLpmResumeSem, SystemP_WAIT_FOREVER);
    
            DebugP_log("[IPC RPMSG ECHO] Main domain resumed due to MCU UART \r\n");
        }
        else if (gbSuspended == 0u)
        {
            UART_readCancel(gUartHandle[CONFIG_UART0], &trans);
            DebugP_log("[IPC RPMSG ECHO] Main domain resumed from a different wakeup source \r\n");
        }
    #endif
        DebugP_memLogWriterResume();
    }

    我认为 Linux 脚本应按如下方式修改(添加 2 秒延迟)

    while true; do echo mem > /sys/power/state; sleep 2; done;

    据我所知、AM62x 进入 LPM 需要~57ms。

    一旦发生唤醒事件、完成此过程需要~277ms。

    (在 SK-AM62-LP 上测试)

    [   74.934434] PM: suspend entry (deep)
    [   74.940791] Filesystems sync: 0.002 seconds
    [   74.962326] Freezing user space processes
    [   74.968598] Freezing user space processes completed (elapsed 0.002 seconds)
    [   74.975654] OOM killer disabled.
    [   74.978887] Freezing remaining freezable tasks
    [   74.984862] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
    [   74.992274] printk: Suspending console(s) (use no_console_suspend to debug)
    
    --> 57ms
    
    
    [   75.008295] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 179: state: 1: ret 0
    [   75.008486] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 178: state: 1: ret 0
    [   75.016090] omap8250 2800000.serial: PM domain pd:146 will not be powered off
    [   75.016769] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 117: state: 1: ret 0
    [   75.016961] ti-sci 44043000.system-controller: ti_sci_cmd_set_latency_constraint: latency: 100: state: 1: ret 0
    [   75.040593] Disabling non-boot CPUs ...
    [   75.043143] psci: CPU1 killed (polled 0 ms)
    [   75.047649] psci: CPU2 killed (polled 0 ms)
    [   75.051339] psci: CPU3 killed (polled 0 ms)
    [   75.053039] Enabling non-boot CPUs ...
    [   75.053478] Detected VIPT I-cache on CPU1
    [   75.053534] GICv3: CPU1: found redistributor 1 region 0:0x00000000018a0000
    [   75.053603] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
    [   75.054937] CPU1 is up
    [   75.055238] Detected VIPT I-cache on CPU2
    [   75.055274] GICv3: CPU2: found redistributor 2 region 0:0x00000000018c0000
    [   75.055323] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
    [   75.056354] CPU2 is up
    [   75.056650] Detected VIPT I-cache on CPU3
    [   75.056686] GICv3: CPU3: found redistributor 3 region 0:0x00000000018e0000
    [   75.056738] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
    [   75.057784] CPU3 is up
    [   75.058442] ti-sci 44043000.system-controller: ti_sci_resume: wakeup source: 0x90
    [   75.075295] am65-cpsw-nuss 8000000.ethernet: set new flow-id-base 19
    [   75.084626] am65-cpsw-nuss 8000000.ethernet eth0: PHY [8000f00.mdio:00] driver [TI DP83867] (irq=POLL)
    [   75.084650] am65-cpsw-nuss 8000000.ethernet eth0: configuring for phy/rgmii-rxid link mode
    [   75.249195] OOM killer enabled.
    [   75.252343] Restarting tasks ... done.
    [   75.258819] random: crng reseeded on system resumption
    [   75.266115] k3-m4-rproc 5000000.m4fss: Core is on in resume
    [   75.271949] k3-m4-rproc 5000000.m4fss: received echo reply from 5000000.m4fss
    [   75.285786] PM: suspend exit
    
    -->277ms

    谢谢你。

    Gibbs

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Gibbs、

    您能否说明这种连续执行 LPM 是否是最终产品的预期用例?  

    请回答 Nick 的问题、以便我们可以进一步调试。

    您提到的延迟数字用于打印语句。 正如我们在上一个主题中讨论的那样、当我们减少打印语句的数量时、延迟会减少。  


    谢谢、

    Anshu

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Anshu 和 Nick

    回复如下。

    Q1/A1:在遇到问题之前、您是否成功执行了多次低功耗模式循环?

    是的,到目前为止,我们有两个圆睾丸。 4K 次 suceess 有一个故障、而 9k 次 suceess 有一个故障。

    因此、为了避免竞态条件潜在问题、我要求 Cutomer 在 MCU 触发 A53 唤醒之前在代码中添加一些延迟(~1 秒)。

    Q2/A2:您正在使用什么唤醒源进行这些测试?   如何触发 M4F 以唤醒系统?

    按照我之前提到的、因为我们发现在 LPM(退出/重新进入)时、有一些潜在的可能性(案例)导致 RPMsg 崩溃、因此我们设计了 “应力测试“以找出根本原因。

    (1) 应力测试:  

    无 GPIO 触发、添加简单延迟、然后唤醒。 我想我已经在前一篇文章中分享了该代码。

     

    (2) 实际用例

    但在实际用例中、MCU(仅 MCU 模式或深度睡眠模式)将读取多个 GPIO 状态 (MCU_GPIO0_19  / MCU_GPIO0_20 / MCU_GPIO0_3 / MCU_GPIO0_14) 以触发 A53 Linux 唤醒、这些 GPIO 信号来自车辆 IGN/WIFI/5G 模块/CAN 总线/USB 唤醒… ETC ,所以它是很有可能多个唤醒事件几乎同时触发。 因为我们怀疑进入/退出 LPM 时 GPIO 唤醒触发过多可能会导致 RPMsg 通信失败,所以我们设计“ Stress test“(压力测试)、用于深度调试。

    我认为 AM62 不会在现场车辆应用中(不会)断电、它仅在 LPM 和正常运行之间工作。 因此、我们需要确保 LPM 唤醒不存在严重问题。

    Q3/A3:您是否使用未经修改的 ipc_rpmsg_echo_linux 示例? 如果您使用的是自定义代码,请让 Gibbs 与我们离线分享该自定义代码。

    按照我之前提到的、 我已经在这里分享了代码。 我们使用默认映像编译 (tisdk-default-image-am62xx-lp-evm-10.01.10.04.rootfs.wic.xz) 和的一些位修改示例代码  IPC rpmsg_echo_linux。  对于 SK-AM62-LP EVM 上的所有测试、您可以直接下载我的工程代码并在 EVM 上运行。  

    Q4/A4:  如果您使用的是自定义 M4F 代码、是否在 DDR 中存储任何程序数据?  

    此问题遵循 Q3/A3。 我想我们不将程序数据存储在 DDR 中、因为我们使用默认示例工程 (r 个人计算机 rpmsg_echo_linux ) 进行一些修改以进行测试。

    Q5/A5 :我们有什么方法来分解看门狗重置?

    这是一个新问题、当我们这样做时“ 应力测试“、 我们发现系统重新启动了一些时间、但需要长时间测试。 我们怀疑当 AM62 触发某个错误异常时、它似乎会触发看门狗复位、然后在 3 分钟后重新启动。 我们之前有非常类似的讨论。

    系统重新启动后、我们会丢失任何日志。 我们能否用任何方法在 AM62 出现 WDT 错误时记录一些信息、并尝试知道让 AM62 重新启动的原因。

    顺便说一下、 我还怀疑“持续执行 LPM “是否合理、因此与客户的讨论仍在继续。

    非常感谢

    Gibbs

     

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Gibbs、

    对于问题 5、我们将继续对以下主题进行讨论: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1534178/am620-q1-tifs-timeout

    谢谢、

    Anshu

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Gibbs、

    1) 在 Linux 低功耗转换之前增加 1 秒时、状态更新?  

    客户进行了多少次测试? 在 Linux 开始下一次低功耗转换之前有 1 秒的延迟、我们是否看到过任何故障?

    2) 感谢您分享测试代码  

    基于 6 月 27 日发布的代码的评论:
    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1532839/am620-q1-ipc-crash-in-resume-from-mcu-only-mode/5896055#5896055 

    a) 如果除 M4F 内核之外的其他器件唤醒处理器、系统可能无法按预期工作(因为用于处理该用例的代码已被注释掉)

    b) 代码仍在调用 UART_Transaction_init。 我认为这应该可以、因为似乎该函数只是初始化 UART 事务结构、实际上并不是启动任何像 UART_read https://software-dl.ti.com/mcu-plus-sdk/esd/AM62X/10_01_00_33/exports/docs/api_guide_am62x/group__DRV__UART__MODULE.html#ga07908a73787a9ef3e8356c51524b8c44 这样运行的内容 

    3) 捕获日志输出  

    您可以在 EVM 上捕获日志、但如果您将计算机连接到 EVM、也可以在计算机上捕获日志(例如,如果您有一台 Linux PC 在整个测试运行期间连接到 EVM)。 根据您用于连接到 EVM 的终端应用程序、应该有多种不同的方法来实现此目的。

    此致、

    Nick

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Walter Wang

    1) 当 Linux 增加 1 秒延迟时、您是否仍看到故障状态更新?

    2) 详细介绍您的 MCU GPIO 唤醒源。

    M4F 是否必须执行任何逻辑来决定 GPIO 信号是否应导致唤醒? 或者、您只是希望 GPIO 状态的任何更改都能触发唤醒?

    听起来 Linux 在运行时正在控制 MCU GPIO 模块。 因此、Linux 是 MCU GPIO 的所有者、而不是 M4F。

    我建议不要使用 M4F 来观察 MCU GPIO 信号、而是将每个 GPIO 输入配置为 Linux 的唤醒源。 这也会简化 M4F 软件开发。

    有关更多信息、请参阅 https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/10_01_10_04/exports/docs/linux/Foundational_Components / Power_Management / pm_wakeup_sources.html 

    此致、

    Nick

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    其中、这是一个不需要逻辑的示例用例:

    4 个不同的 GPIO 信号被定义为唤醒源。
    如果其中任何一个具有上升沿、则唤醒处理器

    这是一个需要 M4F 执行一些逻辑的示例用例:

    4 个不同的 GPIO 信号是唤醒源。
    如果 GPIO1 具有上升沿、则唤醒处理器
    否则、如果 GPIO2 有 3 个脉冲、即 WAKE 处理器
    否则、如果 GPIO3 具有上升沿、则为 WAKE 处理器、但仅当 GPIO4 已为高电平时
    否则、如果 GPIO4 具有上升沿、则为 WAKE 处理器、但仅当 GPIO3 已为高电平时才如此

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Nick、

    目前、我们只遇到 3 分钟内自动重启的问题。

    有关更多详细信息、请通过 Gibbs 与您同步。

    谢谢