你好, Gibbs、
我们已经解决了 MCU 无法在仅模式下控制 IO 的问题。
接下来、请优先解决 MCU 唤醒 soc 并导致 IPC 崩溃和自动重启的问题
谢谢

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.
你好, 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://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
嗨、Nick
感谢您的建议、
首先简单更新状态。
我认为客户想要对 LPM(仅 MCU 模式)唤醒循环进行“压力测试“、所以他们设计了支出、目标是:
(1) 当 AM62 进入 LPM 并通过长时间测试从 LPM 循环唤醒时、是否会导致任何软件崩溃?
(2) 当 AM62“要执行“LPM 过程时、是否导致了任何软件崩溃、但也同时收到唤醒事件?
(3) 当 AM62“从 LPM 过程唤醒“但同时获得“睡眠“事件时、是否会导致任何软件崩溃?
基本上、它们基于我们用于该测试的 IPC_RPMSG_ECHO_Linux 示例代码。
文件作为附件。
密钥代码修改
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
嗨、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
1) 当 Linux 增加 1 秒延迟时、您是否仍看到故障状态更新?
2) 详细介绍您的 MCU GPIO 唤醒源。
M4F 是否必须执行任何逻辑来决定 GPIO 信号是否应导致唤醒? 或者、您只是希望 GPIO 状态的任何更改都能触发唤醒?
听起来 Linux 在运行时正在控制 MCU GPIO 模块。 因此、Linux 是 MCU GPIO 的所有者、而不是 M4F。
我建议不要使用 M4F 来观察 MCU GPIO 信号、而是将每个 GPIO 输入配置为 Linux 的唤醒源。 这也会简化 M4F 软件开发。
此致、
Nick
其中、这是一个不需要逻辑的示例用例:
4 个不同的 GPIO 信号被定义为唤醒源。
如果其中任何一个具有上升沿、则唤醒处理器
这是一个需要 M4F 执行一些逻辑的示例用例:
4 个不同的 GPIO 信号是唤醒源。
如果 GPIO1 具有上升沿、则唤醒处理器
否则、如果 GPIO2 有 3 个脉冲、即 WAKE 处理器
否则、如果 GPIO3 具有上升沿、则为 WAKE 处理器、但仅当 GPIO4 已为高电平时
否则、如果 GPIO4 具有上升沿、则为 WAKE 处理器、但仅当 GPIO3 已为高电平时才如此