工具与软件:
您好、
我通过引用链路中的操作在器件树中添加了 PHY 复位引脚、但它 似乎不起作用。 我用示波器测量了它的水平、发现它没有变化、始终处于高水平。 可能是什么原因? 我们目前使用的是 SDK8.06、Linux 内核版本是5.10。
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.
工具与软件:
您好、
我通过引用链路中的操作在器件树中添加了 PHY 复位引脚、但它 似乎不起作用。 我用示波器测量了它的水平、发现它没有变化、始终处于高水平。 可能是什么原因? 我们目前使用的是 SDK8.06、Linux 内核版本是5.10。
这是最小复位延迟、对吧? 而不是最大值?
我需要查看代码、但如果复位信号由 Linux 软件触发(而不是由基于某种状态条件的硬件电路触发)、那么有时需要看到几毫秒后 Linux 调度程序才会运行实际发送复位信号的代码。
您使用的是 Linux 还是 RT Linux?
如果复位信号由软件触发、那么 RT Linux 应能够提供更确定的响应时间。 但您仍然无法让 Linux 在2微秒内做出响应。 这需要真正的 RTOS、就像在 R5F 上一样。
此致、
Nick
您好、Wanglili、
嗯。 我不太清楚这个延迟值是否在 PHY 已注册并连接到 MII 总线的时间之外使用:
ti-processor-sdk-linux-am64xx-evm-10.01.10.04/board-support/ti-linux-kernel-6.6.58+git-ti/drivers/net$ grep -r 'reset-delay-us'
mdio/of_mdio.c: of_property_read_u32(np, "reset-delay-us", &mdio->reset_delay_us);
ti-processor-sdk-linux-am64xx-evm-10.01.10.04/board-support/ti-linux-kernel-6.6.58+git-ti/drivers/net$ grep -r 'reset_delay_us'
phy/mdio_bus.c: fsleep(bus->reset_delay_us);
ethernet/intel/igc/igc_base.c: phy->reset_delay_us = 100;
ethernet/intel/igc/igc_phy.c: udelay(phy->reset_delay_us);
ethernet/intel/igc/igc_hw.h: u32 reset_delay_us; /* in usec */
ethernet/intel/igb/e1000_82575.c: phy->reset_delay_us = 100;
ethernet/intel/igb/e1000_phy.c: udelay(phy->reset_delay_us);
ethernet/intel/igb/e1000_hw.h: u32 reset_delay_us; /* in usec */
ethernet/intel/e1000e/80003es2lan.c: phy->reset_delay_us = 100;
ethernet/intel/e1000e/82571.c: phy->reset_delay_us = 100;
ethernet/intel/e1000e/ich8lan.c: phy->reset_delay_us = 100;
ethernet/intel/e1000e/ich8lan.c: phy->reset_delay_us = 100;
ethernet/intel/e1000e/phy.c: udelay(phy->reset_delay_us);
ethernet/intel/e1000e/hw.h: u32 reset_delay_us; /* in usec */
ethernet/oki-semi/pch_gbe/pch_gbe.h: * @reset_delay_us: HW reset delay time[us]
ethernet/oki-semi/pch_gbe/pch_gbe.h: u32 reset_delay_us;
ethernet/oki-semi/pch_gbe/pch_gbe_main.c: hw->phy.reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US;
mdio/of_mdio.c: mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY;
mdio/of_mdio.c: of_property_read_u32(np, "reset-delay-us", &mdio->reset_delay_us);
$ vi phy/mdio_bus.c
/**
* __mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
* @bus: target mii_bus
* @owner: module containing bus accessor functions
*
* Description: Called by a bus driver to bring up all the PHYs
* on a given bus, and attach them to the bus. Drivers should use
* mdiobus_register() rather than __mdiobus_register() unless they
* need to pass a specific owner module. MDIO devices which are not
* PHYs will not be brought up by this function. They are expected
* to be explicitly listed in DT and instantiated by of_mdiobus_register().
*
* Returns 0 on success or < 0 on error.
*/
int __mdiobus_register(struct mii_bus *bus, struct module *owner)
{
...
/* assert bus level PHY GPIO reset */
gpiod = devm_gpiod_get_optional(&bus->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(gpiod)) {
...
} else if (gpiod) {
bus->reset_gpiod = gpiod;
fsleep(bus->reset_delay_us);
gpiod_set_value_cansleep(gpiod, 0);
if (bus->reset_post_delay_us > 0)
fsleep(bus->reset_post_delay_us);
}
请注意、当该函数调用 fsleep 时、它会使处理器执行另一个任务。 因此、代码肯定不会在2usec 内运行、但在2usec 过后、如果另一个任务仍在使用处理器、该任务将在 Linux 调度程序允许 MDIO 函数再次运行之前完成其时间片。
Linux 偶尔出现毫秒延迟绝对是正常现象。 您将从 google 搜索中得到更好的解释、但常规的 Linux 调度程序基本上是经过优化的、以便以最佳性能运行最多数量的代码。 这意味着、整个系统应该能相当有效地运行、但也意味着不能保证特定代码段能在特定的时间内运行。
对于具有实时需求的系统(其中"实时"意味着某个任务必须在特定的时间内完成)、我们通常建议使用 RT Linux (比常规 Linux 更实时)或真正的实时操作系统(RTOS)。 RT Linux 允许特定代码几乎在所需的时间范围内一直运行、但由于某些代码段具有更高的优先级、因此总体系统性能可能会稍慢一些。
此致、
Nick