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.

[参考译文] TMDS64EVM:检测 CPU 时钟故障?

Guru**** 2487425 points
Other Parts Discussed in Thread: AM6442, SYSCONFIG

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1430741/tmds64evm-detect-cpu-clock-fault

器件型号:TMDS64EVM
主题中讨论的其他器件:AM6442SysConfig

工具与软件:

您好!

是否有可能检测 CPU 频率波动并告知用户空间这一事实?

BR、

雅库布

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

    你好、Jakub、

    我假设您在 A53内核上使用 Linux、并且询问您是否专门要检测 A53内核中的频率波动?

    请注意、Linux SDK 的早期版本可能导致 PLL 不稳定。 SDK 10.0同时发布了可修复 PLL 不稳定性的更新固件。 有关更多信息、请查看此处: https://software-dl.ti.com/processor-sdk-linux/esd/AM64X/10_00_07_04/exports/docs/devices/AM64X/linux/Release_Specific_Migration_Guide pll.html?highlight=pll

    此致、

    Nick

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

    你好、Nick

    是的、完全是 A53。 很抱歉没有添加更全面的主题说明。 好在这里、PLL 初始化过程在 SDK10中得到了改进。 无论如何、在我们基于 AM6442 CPU 的产品中、我们需要检测在某些情况下 CPU 时钟可能工作错误的情况、并采取一些措施、例如开关继电器和报告错误。 那么、是否有某种 API 可以帮助从用户空间应用级别实现该目标?

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

    我注意到数据表中有 用于此目的的双路时钟比较器(DCC)模块。  我还在 SDK 中找到了一些用于 R5内核的示例代码、但对于 A53内核却找不到任何代码。 你能举个例子吗?

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

    你好、Jakub、

    看起来我们不为 AM64x 上的 Linux 提供 DCC 支持。 请参阅软件构建表:
    https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/10_00_00_20/exports/docs/build_sheet/am64x-sw-buildsheet.html 

    我在 Linux devicetree 中反复检查过、但没有看到任何看起来像双时钟比较器的东西。

    arch/arm64/boot/dts/ti$ grep -r --include=k3-am64* dcc
    arch/arm64/boot/dts/ti$ grep -r --include=k3-am64* dual
    arch/arm64/boot/dts/ti$ grep -r --include=k3-am64* clock
    

    能不能再多讲一讲您所担心的情况?

    例如、如果 AM64x 中的系统时间需要与外部时钟源保持一致、我通常会看到客户通过以太网实现 PTP 之类的来确保时钟对齐。

    此致、

    Nick

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

    Nick:请 在 AM6x 的 Linux SDK v10.2中请求 DCC 支持;可以预见这是 A53内核之外的多个以太网域应用的潜在问题(请 cc: (+) Daolin Qiu 的个人资料- Daolin Qiu - 有关此问题的 TI E2E 支持论坛)

    谢谢、Jim

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

    Jim、您好!

    您是否能够更明确地了解您对潜在问题的预测?

    此致、

    Nick

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

    您好、Nick。

    在一个团队中经过几次协商后、我们决定在 R5内核侧(无 A53)实施我们的功能。 我们希望器件中有某种监控器、可用于监控器件的不同子系统、包括 CPU 时钟。 无论如何、在使用该 API 的 R5上编译代码时、我存在一些问题
    首先、我检查了此 示例 、编译正常。 我检查了此示例工程的 SysConfig、但没有找到任何与 DCC 相关的内容。我包含了头文件  和 . 您能说明如何使链接器可见此 API 吗?
    链接器抱怨:

    [版本]
    首次引用的[Build]未定义
    [BUILD]符号
    [版本]------- -------
    [Build] SDL_DCC_configure Supervision/libSupervision.a
    [Build] SDL_DCC_ENABLE Supervision/libSupervision.a


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

    你好、Jakub、

    我懂了。 我将把您的主题重新分配给一位更熟悉 MCU+ SDK 的团队成员。 这是印度的假日周、因此预计回复会延迟。 如果您在几个工作日内未收到回复、请随意 ping 该主题。

    此致、

    Nick

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

    您好、Nick。

    我只想添加一点、即我们使用的是版本9.00.00.35中的 MCU+SDK。 到目前为止、我们不计划迁移到最新版本。 此 DCC 功能是否也应由 SDK 9.00提供?

    我们的应用的 SYSCFG:

    /**
     * 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@09.00.00"
     * @v2CliArgs --device "AM6442" --package "FCBGA (ALV)" --variant "AM6442-D" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM64x@09.00.00"
     * @versions {"tool":"1.21.0+3721"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const epwm       = scripting.addModule("/drivers/epwm/epwm", {}, false);
    const epwm1      = epwm.addInstance();
    const esm        = scripting.addModule("/drivers/esm/esm", {}, false);
    const esm1       = esm.addInstance();
    const gpio       = scripting.addModule("/drivers/gpio/gpio", {}, false);
    const gpio1      = gpio.addInstance();
    const gpio2      = gpio.addInstance();
    const gpio3      = gpio.addInstance();
    const gpio4      = gpio.addInstance();
    const gpio5      = gpio.addInstance();
    const gpio6      = gpio.addInstance();
    const gpio7      = gpio.addInstance();
    const gpio8      = gpio.addInstance();
    const gpio9      = gpio.addInstance();
    const i2c        = scripting.addModule("/drivers/i2c/i2c", {}, false);
    const i2c1       = i2c.addInstance();
    const ipc        = scripting.addModule("/drivers/ipc/ipc");
    const mcspi      = scripting.addModule("/drivers/mcspi/mcspi", {}, false);
    const mcspi1     = mcspi.addInstance();
    const udma       = scripting.addModule("/drivers/udma/udma", {}, false);
    const udma1      = udma.addInstance();
    const watchdog   = scripting.addModule("/drivers/watchdog/watchdog", {}, false);
    const watchdog1  = watchdog.addInstance();
    const debug_log  = scripting.addModule("/kernel/dpl/debug_log");
    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 mpu_armv77 = mpu_armv7.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    epwm1.$name            = "ADC_MCLK_EPWM4";
    epwm1.EPWM.$assign     = "EHRPWM4";
    epwm1.EPWM.A.$assign   = "GPMC0_OEn_REn";
    epwm1.EPWM.B.$used     = false;
    epwm1.EPWM.SYNCO.$used = false;
    epwm1.EPWM.SYNCI.rx    = false;
    epwm1.EPWM.SYNCI.$used = false;
    
    esm1.$name                      = "CONFIG_ESM0";
    esm1.esmNotifier[0].$name       = "CONFIG_ESM_NOTIFY0";
    esm1.esmNotifier[0].errorNumber = 162;
    esm1.esmNotifier[0].notify      = "ESM_Callback";
    
    gpio1.$name                = "ADC_DRDY";
    gpio1.trigType             = "RISE_EDGE";
    gpio1.GPIO.gpioPin.pu_pd   = "pd";
    gpio1.GPIO.gpioPin.$assign = "GPMC0_CSn0";
    
    gpio2.$name                = "ADC_CONVST_SAR";
    gpio2.pinDir               = "OUTPUT";
    gpio2.GPIO.gpioPin.pu_pd   = "pu";
    gpio2.GPIO.gpioPin.rx      = false;
    gpio2.GPIO.gpioPin.$assign = "GPMC0_BE0n_CLE";
    
    gpio3.$name                = "ADC_START";
    gpio3.pinDir               = "OUTPUT";
    gpio3.GPIO.gpioPin.pu_pd   = "pd";
    gpio3.GPIO.gpioPin.rx      = false;
    gpio3.GPIO.gpioPin.$assign = "GPMC0_BE1n";
    
    gpio4.$name                = "ADC_ALERT_IRQ";
    gpio4.trigType             = "FALL_EDGE";
    gpio4.GPIO.$assign         = "GPIO0";
    gpio4.GPIO.gpioPin.pu_pd   = "pd";
    gpio4.GPIO.gpioPin.$assign = "GPMC0_WAIT1";
    
    gpio5.$name                = "ADC_SYNC_TEST_OUT";
    gpio5.pinDir               = "OUTPUT";
    gpio5.GPIO.gpioPin.rx      = false;
    gpio5.GPIO.gpioPin.$assign = "GPMC0_WPn";
    
    gpio6.$name                = "PRU_PPS_IRQ";
    gpio6.trigType             = "RISE_EDGE";
    gpio6.GPIO.$assign         = "GPIO0";
    gpio6.GPIO.gpioPin.pu_pd   = "pd";
    gpio6.GPIO.gpioPin.$assign = "PRG1_PRU0_GPO3";
    
    gpio7.$name                = "BIO_INT_A";
    gpio7.trigType             = "FALL_EDGE";
    gpio7.GPIO.$assign         = "GPIO0";
    gpio7.GPIO.gpioPin.pu_pd   = "pu";
    gpio7.GPIO.gpioPin.$assign = "GPMC0_WAIT0";
    
    gpio8.$name                = "BIO_INT3";
    gpio8.trigType             = "FALL_EDGE";
    gpio8.GPIO.$assign         = "GPIO0";
    gpio8.GPIO.gpioPin.pu_pd   = "pu";
    gpio8.GPIO.gpioPin.$assign = "OSPI0_CSn3";
    
    gpio9.$name                = "RTC_PPS_IRQ";
    gpio9.trigType             = "RISE_EDGE";
    gpio9.GPIO.$assign         = "GPIO0";
    gpio9.GPIO.gpioPin.$assign = "GPMC0_CSn2";
    
    i2c1.$name       = "MEAS_CARD_I2C1";
    i2c1.I2C.$assign = "I2C1";
    
    ipc.enableLinuxIpc = true;
    ipc.r5fss0_1       = "NONE";
    ipc.r5fss1_0       = "NONE";
    ipc.r5fss1_1       = "NONE";
    ipc.m4fss0_0       = "NONE";
    
    mcspi1.$name                       = "CONFIG_MCSPI0";
    mcspi1.intrEnable                  = "DMA";
    mcspi1.intrPriority                = 2;
    mcspi1.transferMode                = "CALLBACK";
    mcspi1.transferCallbackFxn         = "MCSPI0_TransferCallback";
    mcspi1.advanced                    = true;
    mcspi1.mcspiChannel[0].$name       = "CONFIG_MCSPI_CH0";
    mcspi1.mcspiChannel[0].bitRate     = 15000000;
    mcspi1.mcspiChannel[0].frameFormat = "POL0_PHA1";
    
    udma1.$name       = "CONFIG_UDMA0";
    mcspi1.udmaDriver = udma1;
    
    watchdog1.$name          = "CONFIG_WDT0";
    watchdog1.expirationTime = 45000;
    watchdog1.resetMode      = "Watchdog_RESET_OFF";
    watchdog1.instance       = "WDT8";
    
    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_REGION5";
    mpu_armv75.baseAddr = 0x80000000;
    mpu_armv75.size     = 31;
    
    mpu_armv76.$name        = "TCMB_R5F";
    mpu_armv76.attributes   = "NonCached";
    mpu_armv76.allowExecute = false;
    mpu_armv76.size         = 15;
    mpu_armv76.baseAddr     = 0x41010000;
    
    mpu_armv77.$name        = "CONFIG_MPU_REGION6";
    mpu_armv77.size         = 20;
    mpu_armv77.baseAddr     = 0xA0000000;
    mpu_armv77.attributes   = "NonCached";
    mpu_armv77.allowExecute = false;
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    gpio1.GPIO.$suggestSolution                 = "GPIO0";
    gpio2.GPIO.$suggestSolution                 = "GPIO0";
    gpio3.GPIO.$suggestSolution                 = "GPIO0";
    gpio5.GPIO.$suggestSolution                 = "GPIO0";
    i2c1.I2C.SCL.$suggestSolution               = "I2C1_SCL";
    i2c1.I2C.SDA.$suggestSolution               = "I2C1_SDA";
    mcspi1.SPI.$suggestSolution                 = "SPI0";
    mcspi1.SPI.CLK.$suggestSolution             = "SPI0_CLK";
    mcspi1.SPI.D0.$suggestSolution              = "SPI0_D0";
    mcspi1.SPI.D1.$suggestSolution              = "SPI0_D1";
    mcspi1.mcspiChannel[0].CSn.$suggestSolution = "SPI0_CS0";
    

    BR、

    雅库布

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

    你好、Jakub、

    对于此处的延迟、我们深表歉意。

    是的、9.0 MCU+SDK 中也支持 DCC。 DCC 初始化直接在应用程序本身中完成、因此您在 syscfg 工具中看不到它。  

    您可以浏览演示的 DCC 示例、如果您对 DCC 配置等有任何其他问题、请告诉我  

    (mcu_plus_sdk_am64x_09_00_00_35/examples/sdl/DCC/DCC_modes)

    此致、

    Nihar Potturu.  

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

    您好 Nihar:

    感谢您的响应。 目前、我拥有初始化并运行 DCC 外设的代码。 现在我要通过动态更改时钟源频率来测试它、并查看是否触发了错误中断。 为此、我使用了 k3conf 工具、键入命令: k3conf 设置时钟16 6 25000000、这应该会将时钟源6频率更改为所需的频率。 但实际上没有发生任何情况...

    root@puma:~# k3conf 设置时钟16 6 25000000
    ||---------------------------------------------------------- |
    | VERSION INFO |
    ||---------------------------------------------------------- |
    | K3CONF |(版本 v0.1-88-g982f5c2已构建、周一11月4日上午11:02:54 UTC 2024)|
    | SoC | AM64x SR2.0 |
    | SYSFW | ABI:3.1 (固件版本0x0008 '8.6.4--v08.06.04 (Chill Capybar)')|
    ||---------------------------------------------------------- |

    ||----------------------------------------------------------- |
    |器件 ID |时钟 ID |时钟名称|状态|时钟频率|
    ||----------------------------------------------------------- |
    | 16 | 0 | DEV_DCC0_DCC_CLKSRC0_CLK | CLK_STATE_READY | 200000000 |
    | 16 | 1 | DEV_DCC0_DCC_CLKSRC1_CLK | CLK_STATE_READY | 80000000 |
    | 16 | 2 | DEV_DCC0_DCC_CLKSRC2_CLK | CLK_STATE_READY | 133333333 |
    | 16 | 3 | DEV_DCC0_DCC_CLKSRC3_CLK | CLK_STATE_READY | 250000000 |
    | 16 | 4 | DEV_DCC0_DCC_CLKSRC4_CLK | CLK_STATE_READY | 25000000 |
    | 16 | 5 | DEV_DCC0_DCC_CLKSRC5_CLK | CLK_STATE_READY | 0 |
    | 16 | 6 | DEV_DCC0_DCC_CLKSRC6_CLK | CLK_STATE_READY | 500000000 |
    | 16 | 7 | DEV_DCC0_DCC_CLKSRC7_CLK | CLK_STATE_READY | 60000000 |
    | 16 | 8 | DEV_DCC0_DCC_INPUT00_CLK | CLK_STATE_READY | 25000000 |
    | 16 | 9 | DEV_DCC0_DCC_INPUT01_CLK | CLK_STATE_READY | 0 |
    | 16 | 10 | DEV_DCC0_DCC_INPUT02_CLK | CLK_STATE_READY | 12500000 |
    | 16 | 11 | DEV_DCC0_DCC_INPUT10_CLK | CLK_STATE_READY | 250000000 |
    | 16 | 12 | DEV_DCC0_VBUS_CLK | CLK_STATE_READY | 125000000 |
    ||----------------------------------------------------------- |

    DEV_DCC0_DCC_CLKSRC6_CLK  仍然具有500 MHz 频率。 您能否详细说明一下应该如何使用此工具?

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

    我想检查 DCC 代码是否正常工作的唯一方法是特意将 CLK_SRC 计时器计数初始化为错误值、以触发 ESM 错误中断(我的意思是 DCC0_INTR_ERR_LEVEL_0 (112)、来自参考手册页面:5829)。 但在这种情况下、电路板几乎在应用启动后立即复位。 默认行为也是如此  触发中断时 ESM 复位 SoC? 我能否通过读取某些持久寄存器或其他内容来以某种方式检测重启的根本原因?

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

    你好、Jakub、

    我将介绍您分享的其他要点。 请给我几天的时间来回答这些问题。

    我能否通过读取某些永久性寄存器或其他内容来以某种方式检测重启的根本原因?

    您可以使用 RST_SRC 寄存器来获取复位原因。

    此致、

    Nihar Potturu.  

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

    您好 Nihar

    感谢您的响应。 关于寄存器0x24/0x28中的关键位、TRM 中未明确提及这一点、但我认为只需要更改时钟源然后将其清除-这可能是保险丝针对意外误配置的情况。 总之、我的代码正常工作。 我发现电路板重启与 ESM 中断的优先级有关。 如果它为高电平、那么一旦出现中断、那么电路板立即重新启动。 我通过特意将 DCC 计数器1编程为与当前时钟频率相关的错误值来测试该解决方案、以查看是否发生错误中断-确实如此。 但我宁愿使用动态更改时钟的频率  k3conf 调用命令来调用工具  k3conf 设置时钟16 6 25000000。  正如我先前提到的、该命令不起作用、时钟频率保持不变。 您能为我提供这方面的支持吗? 我不知道我是否应该为此创建另一个主题、还是继续在这里讨论?