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.

[参考译文] PHYTC-3P-PHYCORE-AM335X:如果 PRU 正在运行、则为 USB 内核紧急状态

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1172164/phytc-3p-phycore-am335x-usb-kernel-panic-if-pru-is-running

器件型号:PHYTC-3P-PHYCORE-AM335X

此线程引用的是在写入 USB 时针对内核严重错误而创建的另一个线程。

我们发现、它似乎仅在 PRU 运行时发生。

我们的 PRU 代码与 TIDA0155示例非常相似: https://git.ti.com/cgit/apps/tida01555/

我们使用其中一个 PRU 内核作为 SPI 总线、另一个 PRU 内核将数据读取并写入 DDR 存储器中的某个位置。

我们在 DTS 文件中保留了这部分内存、我修改了 PRU 驱动程序以接受 memory-region 命令、也重新映射了此部分。

/*为 PRU 缓冲区保留128KB DDR 存储器*/
/{
  保留存储器{
    #address-cells =<1>;
    大小单元格=<1>;
    范围;

    PRU_RESERVED:PRU_RESERVED@0x9ffc0000{
      reg =<0x9ffc0000 0x00020000>;
      无地图;
    };
  };
};

以下是/proc/iomem 结果、表明该段不包括在内:

8000000000-9ffbFFFF:系统 RAM
 80008000-809fff:内核代码
 80b00000-810e87e7:内核数据
9ffe0000-afefffff:系统 RAM
b0000000-bffffffffff:系统 RAM

我们的应用代码使用 mmap 来连接该区域。 在该设置中、所有操作均按预期工作。

 PRU_MEM =(t_PRU_cmd *) mmap (0、getpagesize ()*32、PROT_READ | PROT_WRITE、MAP_SHARED、PRU_FD、PRU_MEM_START_LOC);

插入 USB 磁盘时、我们还有另一个过程会将一些数据写入到该文件中。 当 PRU 运行时、稍后我们将遇到内核严重错误。

内核严重错误始终是由于虚拟地址空间0xFFEF_Fxxx 处的未处理内核寻呼请求所致、其中 xxx 可能是不同的值。

最近、我还注意到* PgD 的 值通常与0xAFE_D861相同。 我不确定这个地点的重要性。

起初、我认为这在 PRU DDR 位置的范围内、但情况并非如此。 它在它之外。

引用的线程中显示了更完整的内核紧急情况。

如果 PRU 在 USB 处于中断或其他状态时尝试读取/写入 DDR、是否会发生某种类型的问题? 当 USB 写入散聚列表时、USB 使用的缓冲区就好像被破坏了一样。 我不确定是什么原因导致了这种情况。

[17472.778646] 8<--剪切此处----

[17472.816034]无法在虚拟地址 ffeff400处处理内核分页请求

[17472.904550] PgD = f30404e2

[17472.937623][ffeff400]* PgD=afefd861、* Pte=00000000、* Ppte=00000000

[17473.014446]内部错误:Oops:37 [#1]抢占 ARM

[17473.076287]中链接的模块:sd_mod USB_storage scsi_mod PRU_rproc IRQ_pruss_inTC pruss_omap_mailbox

[17473.190415] CPU:0 PID:4339通信:USB 存储未被污染5.10.65-AM335x #1

[17473.274647]硬件名称:通用 AM33XX (平展器件树)

[17473.349301] PC 位于__raW_writesl+0x1c/0xd4

[17473.401559 ] LR 位于 MUSB 默认值 WRITE_Fifo+0xa4/0xc4

[17473.46466]电脑:[ ]   LR:[ ]   PSR:20050093

[17473.541231] sp:c4be5bb0 IP:00000000 fp:c4be5bd4

[17473.605204] R10:c10db9e4 R9:c4d59c80 R8:c4d59c80

[17473.66977] r7:c4d59cb4 r6:f011dc28 r5:00000200 r4:ffeff400

[17473.749141] R3:00000000 R2:0000007c R1:ffeff400 r0:f011dc28

[17473.829105]标志:nzCv 在  模式 SVC_32 ISA ARM 段上关闭 FIQ

[17473.917602]控制:10c5387d 表:83ed4019 DAC:00000051

[17473.987971]处理 USB 存储(pid:4339、栈限制= 0x83bd0ec4)

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

    您好 Jason、

    该日志显示了 USB 驱动程序写入 USB FIFO 时发生的内核页面故障。 我需要进一步思考正在发生的情况、以及它如何与您的 PRU 应用相关。

    您在 AM335x 上使用的是哪种处理器 SDK 版本?

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

    您好、Bin、

    感谢您的回复。 我们使用的 SDK 位于 :https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tag/?h=08.01.00.003

    我将提供 一个您可以加载到 PRU 内核中的最小示例。 它只会写入和读取与我们使用的地址非常相似的 DDR 地址。 它应该会导致与我们在 PRU 处于"运行"状态时看到的相同的内核严重错误。 如果关闭 PRU 代码、则不会出现恐慌。

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

    您好、Bin、

    我获得了一个运行的最小示例、该示例将导致我们看到的相同内核恐慌。

    请将"PRU0_DDR_example.out"文件上传到您的电路板。 您可以将其放置在任意位置,但必须建立一个到 Remoteproc0固件位置的符号链接:

    LN -s /home/root/PRU/PRU0_DDR_Example.out /lib/firmware/am335x-pru0-fw

    或者、您可以重命名*。out 文件并替换现有的 AM335x-pru0-FW 文件。

    PRU 代码处于每20ms 激活一次的 while 循环中。 它将向 DDR 缓冲器写入4、000个位置、然后从 DDR 缓冲器读取4、000个位置。 然后、它将确定执行该步骤所需的时间、并重复该循环、使其每20ms 启动一次。 如果完成时间超过20ms、它将等待20ms、然后再重新启动。 (4、000有点极端、但有助于加快发生恐慌)

    若要启动 PRU0内核、请执行以下操作:echo "start">/sys/class/remoteproc/remoteproc0/state

    插入格式化为 FAT32的 USB。 开始向其写入数据。 对于我之前展示的示例脚本、请参考此问题顶部链接的另一个线程。 在本例中、我启动了两次脚本(使用&在命令之后将其发送到后台)、并且内核恐慌在10分钟内发生。 (您写入的数据越多、发生恐慌的速度就越快)。 然后我重新启动并重试了它,然后又花了2个小时才惊慌。 在我们将其标记为已解决之前、我们需要连续24小时进行写入。

    确保修改 DTS 文件以保留 PRU 将在其中写入 DDR 的存储器部分。 您可以使用我在顶柱中具有的相同功能。 我不认为需要修改驱动程序、因为当我回顾我的笔记时、我保留的 RAM 区域已从/proc/iomem 文件中排除。

    e2e.ti.com/.../PRU0_5F00_DDR_5F00_Example.zip

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

    您好 Jason、

    我支持 USB、但对 PRU 一无所知。

    [引用 userid="213796" URL"~/support/processors-group/processors/f/processors-forum/1172164/phytc-3p-phycore-am335x-usb-kernel-panic-if-pru-is-running "]

    我们的应用代码使用 mmap 来连接该区域。 在该设置中、所有操作均按预期工作。

     PRU_MEM =(t_PRU_cmd *) mmap (0、getpagesize ()*32、PROT_READ | PROT_WRITE、MAP_SHARED、PRU_FD、PRU_MEM_START_LOC);

    [/报价]

    这是 PRU 或 Linux 应用程序上运行的代码是否与 PRU 通信? 如果这是 mmap 保留的内存@0x9ffc0000,mmap()的第一个参数是否应该是这个物理地址而不是0?

    getpagesize()返回4KB?

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

    您好、Bin、

    我认为0用于虚拟内存映射位置、而不是物理位置。 由于它是0、我们告诉内核我们不关心它在哪里实际映射它。 PRU_MEM_START_LOC 是物理 RAM 中的0x9FFC_0000地址。  

    我使用了与示例 相同的代码:https://git.ti.com/cgit/apps/tida01555/tree/ARM_User_Space_App/arm_user_space_app.c

    getpagesize()确实返回4096。

    随 mmap 显示的代码正在 Linux 用户空间上运行。

    此外、当您转到启动 PRU 时、您的 PRU0可能会与 remoteproced1关联、而不是 remoteproc0关联。 您的板上的 Remoteproc 0将用于 AM335x 上的其他 M4、该 M4会执行功耗方面的操作。 我继续删除了它、所以我只具有 remoteprocedure0、1。 您很可能具有0、1、2。

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

    您好 Jason、

    是的、您回答正确。 我没有仔细阅读"man 2 mmap"。 实际上、在大多数情况下、第一个参数应为0、因为我们让内核选择虚拟地址、最后一个参数是要映射的物理地址...

    我将按照您的指示尝试在 EVM 上重现问题、并确定如何对其进行调试。 下周是美国的假日、请期待延迟更新。

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

    没问题! 感谢您的观看。 顺便说一下,您甚至不需要运行用户空间应用程序,就会出现紧急情况。 只要 PRU 代码正在读取/写入 DDR、您就会遇到紧急情况。  

    这就是为什么我们一直在这样做的原因、我们的主应用程序启动 PRU、当它退出时、它不会停止它们。 我们的所有测试都是在 PRU 运行的情况下完成的、我们从未想过它会干扰 USB。 PRU 代码是我们的主要应用程序的核心,因此在我们的生产代码中,我们不能选择关闭它们。  

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

    您好 Jason、

    感谢您提供详细信息。 我们现在知道与内核 USB 驱动程序和 PRU 固件有关。 是否必须尝试修改 PRU 代码以不执行任何操作、例如仅执行繁忙循环而不执行读/写 DDR、以查看问题是否仍然发生? 我想看看我们是否可以将其缩小一点。

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

    您好、Bin、

    我今天早上开始了一个测试案例、其中 PRU 内只有一个忙环路、没有 DDR 访问。 我的直觉告诉我、这不会触发恐慌、因为 PRU 是内核中的自包含模块。 我将告诉您测试结果。

    是否仍有打印出 USB 模块正在读取/写入数据的物理 DDR 位置? 这可用于查看是否在我们设置的 DDR 保留位置区域内设置了任何内容。

    USB 中有太多的层、我很难确定哪个层实际处理数据的保留存储器。 我们在启用 DMA 时、仅在 PIO 上出现了内核严重错误。 从我们之前的测试中可以看到、当它绕过 DMA 时、出现了紧急情况、因为它已经在使用中/忙。

    根据我之前在链接论坛帖子中的笔记:

    我 对出现此问题的原因有一些看法:

    1. USB 模块正在对 PRU 保留的 DDR 区域内的缓冲区进行读取/写入。

    2. PRU 和 USB 之间的 DDR 访问存在某种类型的优先级问题。

    USB 看到 DMA 已经忙、回到访问队列、但 USB 模块本身内部会出现某种类型的优先级问题。

    这是 AM335x TRM 中显示 USB 连接的图。 它通过 L3慢互连进行连接。

    这是 AM335x TRM 中显示 PRU 连接的图。 它显示了 PRU0内核通过 L3快速互连进行连接。

    我不确定互连优先级是如何工作的。 通过 L3慢速互连的 USB 连接是否可以被 L3快速互连访问中断? 我在 TRM 中看到过一些关于互连服务质量的提到、但我没有找到每个外设的任何默认排序。   

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

    您好 Jason、

    [引用 userid="213796" URL"~/support/processors-group/processors/f/processors-forum/1172164/phytc-3p-phycore-am335x-usb-kernel-panic-if-pru-is-running/4415098 #4415098"]我今天上午开始了一个测试案例、其中 PRU 中只有一个繁忙的循环、没有 DDR 访问。 我的直觉告诉我、这不会触发恐慌、因为 PRU 是内核中的自包含模块。

    我有相同的感觉。

    USB 缓冲区分配在独立于平台的 USB 内核驱动程序中完成。 我认为在驱动程序 URB 分配例程中很难找到错误。 但我将检查是否可能打印缓冲区物理地址。 在 DMA 模式下可能可以实现、但在 PIO 模式下不容易实现。

    在周末、我有 一个不同的想法来调试这种情况-由于缓冲区溢出是一个常见的软件错误、我们可能需要检查 PRU 代码中是否存在这种情况。 您可以为 PRU 程序保留3个128KB DDR、但仅使用 PRU 代码中的中间128KB 区域、并将第一个和第三个128KB 区域保留为边界保护。

    如果仍然发生相同的内核恐慌、我们需要查看不同的方向。 但是、如果在运行24小时后没有发生这种情况、您可以检查这些存储器区域以查看它们是否已被修改。 (您可以在 PRU 代码初始化例程中使用数据模式(例如0x00或0xff)填充第一个和第三个128KB、)

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

    您好、Bin、

    好主意。 我还将为该案例创建一些测试代码。 我将编写一个 C 程序 、该程序 也会将存储器地址的值打印到文件中。 这将有助于确定这是否是溢出问题。

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

    您好、Bin、

    我一直在使用超大的保留存储器部分运行测试、并且仍然遇到内核严重错误。 当我打印出存储器的值时、前128KB 和后128KB 中的所有内容都没有被触摸。 它仍然具有我在那里放置的相同初始化值(0xDEADBEF)。

    当发生内核紧急情况时、最后一行始终为:

    注意:使用 preemp_count 2退出 USB 存储

    preemp_count 2是什么意思? 我是否可以尝试任何与抢占相关的内核选项?