SJA1110车载以太网TC10休眠唤醒技术解析

版权申诉
5星 · 超过95%的资源 8 下载量 193 浏览量 更新于2024-09-08 1 收藏 836KB PDF 举报
"此资源是一份关于车载以太网休眠与唤醒的应用提示文档,主要针对NXP的SJA1110车载以太网交换机,涵盖了OPEN Alliance TC10的相关标准。" 在车载网络技术中,以太网作为一种高效的数据传输方案,已经被广泛应用。TC10(Task Group 10)是OPEN Alliance(开放汽车联盟)制定的一个标准,专门关注车载以太网的节能特性,如休眠和唤醒功能。这份文档深入浅出地介绍了如何利用SJA1110芯片实现这些功能。 SJA1110是NXP公司设计的一款专为车载环境设计的以太网交换机,它支持六个独立配置的100BASE-T1端口(P5到P10),每个端口都可以根据TC10标准单独设置休眠和唤醒模式。100BASE-T1是一种单对双绞线的以太网技术,能够提供100Mbps的速率,适用于汽车内部的通信需求。 文档中提到了“Wakeup Matrix”,这是一个关键特性,允许用户自定义每个端口的唤醒行为。这包括从网络上的特定信号触发唤醒,或者通过本地激活的“Wake/Signal Pins”进行唤醒。这些功能使得SJA1110能够在不影响整体系统性能的同时,有效地节省能源。 此外,为了实现休眠模式,车辆需要有一个始终开启的电源供应,即使在设备进入休眠状态时也要保持活动,以便在接收到唤醒信号时能快速响应。INH(抑制)引脚用于控制电压调节器,确保在休眠期间适当关闭不必要的电源,同时在需要时能够迅速恢复工作。 Wakeup Configuration部分详细阐述了如何设置唤醒机制,包括转发机制,使得唤醒信号能够通过级联的SJA1110设备传递,确保整个网络系统的协同工作。 这份文档是理解车载以太网TC10休眠与唤醒机制的重要参考资料,对于工程师们在设计和优化车载网络系统时,尤其是在考虑能源效率和快速响应时间方面,具有很高的参考价值。通过学习这份文档,读者可以更好地掌握SJA1110芯片的高级功能,并且能够灵活应用在实际的车载网络项目中。

static void nvme_calc_irq_sets(struct irq_affinity *affd, unsigned int nrirqs) { struct nvme_dev *dev = affd->priv; unsigned int nr_read_queues, nr_write_queues = dev->nr_write_queues; if (!nrirqs) { nrirqs = 1; nr_read_queues = 0; } else if (nrirqs == 1 || !nr_write_queues) { nr_read_queues = 0; } else if (nr_write_queues >= nrirqs) { nr_read_queues = 1; } else { nr_read_queues = nrirqs - nr_write_queues; } dev->io_queues[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; affd->set_size[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; dev->io_queues[HCTX_TYPE_READ] = nr_read_queues; affd->set_size[HCTX_TYPE_READ] = nr_read_queues; affd->nr_sets = nr_read_queues ? 2 : 1; }static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues) { struct pci_dev *pdev = to_pci_dev(dev->dev); struct irq_affinity affd = { //ָ���ж��׺��Եļ��㷽���Ͳ��� .pre_vectors = 1, .calc_sets = nvme_set_irq_affinity, //nvme_calc_irq_sets, .priv = dev, }; unsigned int irq_queues, poll_queues; poll_queues = min(dev->nr_poll_queues, nr_io_queues - 1); dev->io_queues[HCTX_TYPE_POLL] = poll_queues; dev->io_queues[HCTX_TYPE_DEFAULT] = 1; dev->io_queues[HCTX_TYPE_READ] = 0; irq_queues = 1; if (!(dev->ctrl.quirks & NVME_QUIRK_SINGLE_VECTOR)) irq_queues += (nr_io_queues - poll_queues); return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues, PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd); } 在 Linux 5.17.12 内核版本中,如何修改 pci_alloc_irq_vectors_affinity() 函数的 affinity_hint 参数来绑定 NVMe 驱动的所有 I/O 队列到同一 CPU 核心上。代码展示

2023-06-09 上传

static void nvme_calc_irq_sets(struct irq_affinity *affd, unsigned int nrirqs) { struct nvme_dev *dev = affd->priv; unsigned int nr_read_queues, nr_write_queues = dev->nr_write_queues; if (!nrirqs) { nrirqs = 1; nr_read_queues = 0; } else if (nrirqs == 1 || !nr_write_queues) { nr_read_queues = 0; } else if (nr_write_queues >= nrirqs) { nr_read_queues = 1; } else { nr_read_queues = nrirqs - nr_write_queues; } dev->io_queues[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; affd->set_size[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; dev->io_queues[HCTX_TYPE_READ] = nr_read_queues; affd->set_size[HCTX_TYPE_READ] = nr_read_queues; affd->nr_sets = nr_read_queues ? 2 : 1; }static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues) { struct pci_dev *pdev = to_pci_dev(dev->dev); struct irq_affinity affd = { //ָ���ж��׺��Եļ��㷽���Ͳ��� .pre_vectors = 1, .calc_sets = nvme_set_irq_affinity, //nvme_calc_irq_sets, .priv = dev, }; unsigned int irq_queues, poll_queues; poll_queues = min(dev->nr_poll_queues, nr_io_queues - 1); dev->io_queues[HCTX_TYPE_POLL] = poll_queues; dev->io_queues[HCTX_TYPE_DEFAULT] = 1; dev->io_queues[HCTX_TYPE_READ] = 0; irq_queues = 1; if (!(dev->ctrl.quirks & NVME_QUIRK_SINGLE_VECTOR)) irq_queues += (nr_io_queues - poll_queues); return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues, PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd); } 在 Linux 5.17.12 内核版本中,可以通过修改 pci_alloc_irq_vectors_affinity() 函数的 affinity_hint 参数来绑定 NVMe 驱动的所有 I/O 队列到同一 CPU 核心上。

2023-06-09 上传