PCIe总线-Linux内核PCIe软件框架分析(十一)

1.简介

Linux内核PCIe软件框架如下图所示,按照PCIe的模式,可分为RC和EP软件框架。RC的软件框架分为五层,第一层为RC Controller Driver,和RC Controller硬件直接交互,不同的RC Controller,其驱动实现也不相同;第二层为Core层,该层将Controller进行了抽象,提供了统一的接口和数据结构,将所有的Controller管理起来,同时提供通用PCIe设备驱动注册和匹配接口,完成驱动和设备的绑定,管理所有PCIe设备;第三层为PCIe设备驱动层,包含了Storage、Ethernet、PCI桥等设备驱动;第四层为设备驱动层,根据设备类型,可分为字符设备驱动、网络设备驱动和块设备驱动。第五层为虚拟文件系统层,该层会在用户空间创建设备节点,提供了应用程序访问PCIe设备的路径。EP的软件框架分为六层,第一层为EP Controller Driver,和RC Controller Driver的功能相似;第二层为EP Controller Core层,该层向下将EP Controller进行了抽象,提供了统一的接口和数据结构,将所有的EP Controller管理起来;第三层为EP Function Core,该层统一管理EPF驱动和EPF设备,并提供两者相互匹配的方法;第四层为EP Configfs,在用户空间提供了配置和绑定EPF的接口,用户可以通过这些接口配置EPF,而无需修改驱动;第五层为EP Function Driver,和PCIe设备的具体功能相关;第六层为虚拟文件系统层,和RC的功能相同(EP也有设备驱动层,篇幅所限,图中未画出)。

PCIe软件框架

2.RC软件框架

2.1.RC Controller Driver

RK3588 PCIe RC Controller Driver驱动定义如下所示。

MODULE_DEVICE_TABLE(of, rk_pcie_of_match);
static struct platform_driver rk_plat_pcie_driver = {.driver = {.name	= "rk-pcie",.of_match_table = rk_pcie_of_match,.suppress_bind_attrs = true,.pm = &rockchip_dw_pcie_pm_ops,},.probe = rk_pcie_probe,
};module_platform_driver(rk_plat_pcie_driver);

2.2.Core

2.2.1.Host Bridge

RC Core层使用struct pci_host_bridge数据结构描述Host Bridge。bus描述Root bus,其他bus都在该数据结构的链表中。opschild_ops描述Root bus和其他bus上的设备的配置空间访问方法。windows链表保存bus-range和ranges的资源。dma_ranges链表保存dma-ranges的资源。使用pci_alloc_host_bridgedevm_pci_alloc_host_bridge函数分配struct pci_host_bridge数据结构,使用pci_free_host_bridge释放struct pci_host_bridge数据结构。pci_host_probe枚举Host Bridge下面所有PCIe设备。

[include/linux/pci.h]
struct pci_host_bridge {struct device	dev;struct pci_bus	*bus;		/* Root bus */struct pci_ops	*ops;       /* Low-level architecture-dependent routines */struct pci_ops	*child_ops;void		*sysdata;int		busnr;struct list_head windows;	 /* resource_entry */struct list_head dma_ranges; /* dma ranges resource list */......
};
struct pci_host_bridge *pci_alloc_host_bridge(size_t priv);
struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev,size_t priv);
void pci_free_host_bridge(struct pci_host_bridge *bridge);
int pci_host_probe(struct pci_host_bridge *bridge);

struct pci_ops描述访问PCIe设备配置空间的方法,需要RC Controller Driver实现。常用的是map_busreadwritemap_bus用于映射访问配置空间的region,readwrite用于读写配置空间。

[include/linux/pci.h]
struct pci_ops {int (*add_bus)(struct pci_bus *bus);void (*remove_bus)(struct pci_bus *bus);void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where);int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
};
2.2.2.Bus

RC Core层使用struct pci_bus数据结构描述PCIe bus。所有PCIe bus组成一个PCIe树型结构。parent指向Parent buses,children指向Child buses。devices链表保存该bus上的所有设备。number为该bus的总线编号,primary表示上游总线编号,busn_res保存桥下游总线编号范围,max_bus_speed表示该bus支持的最大速度,cur_bus_speed表示该bus当前的速度。pci_find_bus根据PCIe域和总线编号查找struct pci_buspci_add_new_bus创建一个struct pci_bus并添加到父总线上,注册Host Bridge时会自动创建bus0的数据结构,pci_bus_insert_busn_respci_bus_update_busn_res_end更新PCIe bus编号资源。

[include/linux/pci.h]
struct pci_bus {struct list_head node;		/* Node in list of buses */struct pci_bus	*parent;	/* Parent bus this bridge is on */struct list_head children;	/* List of child buses */struct list_head devices;	/* List of devices on this bus */struct pci_dev	*self;		/* Bridge device as seen by parent */struct list_head slots;		/* List of slots on this bus;protected by pci_slot_mutex */struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];struct list_head resources;	/* Address space routed to this bus */struct resource busn_res;	/* Bus numbers routed to this bus */struct pci_ops	*ops;		/* Configuration access functions */struct msi_controller *msi;	/* MSI controller */void		*sysdata;	/* Hook for sys-specific extension */struct proc_dir_entry *procdir;	/* Directory entry in /proc/bus/pci */unsigned char	number;		/* Bus number */unsigned char	primary;	/* Number of primary bridge */unsigned char	max_bus_speed;	/* enum pci_bus_speed */unsigned char	cur_bus_speed;	/* enum pci_bus_speed */......
};struct pci_bus *pci_find_bus(int domain, int busnr);
struct pci_bus *pci_add_new_bus(struct pci_bus *parent,struct pci_dev *dev, int busnr);
void pci_remove_bus(struct pci_bus *bus);int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
2.2.3.Device

RC Core层使用struct pci_dev数据结构描述PCIe Devices。devfn表述device和function编号,vendordevice等保存PCIe设备配置空间头信息,driver指向该设备使用的驱动。resource保存设备的资源,如BAR、ROMs等。PCIe bus也是一个PCIe设备。pci_alloc_dev分配struct pci_dev数据结构,pci_dev_put释放struct pci_dev数据结构,pci_device_add向总线上添加PCIe设备。pci_bus_add_devicespci_bus_add_device匹配PCIe设备和PCIe驱动。

[include/linux/pci.h]
/* The pci_dev structure describes PCI devices */
struct pci_dev {struct list_head bus_list;	/* Node in per-bus list */struct pci_bus	*bus;		/* Bus this device is on */struct pci_bus	*subordinate;	/* Bus this device bridges to */void		*sysdata;	/* Hook for sys-specific extension */struct proc_dir_entry *procent;	/* Device entry in /proc/bus/pci */struct pci_slot	*slot;		/* Physical slot this device is in */unsigned int	devfn;		/* Encoded device & function index */unsigned short	vendor;unsigned short	device;unsigned short	subsystem_vendor;unsigned short	subsystem_device;unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */......struct pci_driver *driver;	/* Driver bound to this device */......int		cfg_size;		/* Size of config space *//** Instead of touching interrupt line and base address registers* directly, use the values stored here. They might be different!*/unsigned int	irq;struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */bool		match_driver;		/* Skip attaching driver */......
};struct pci_dev *pci_alloc_dev(struct pci_bus *bus);
void pci_dev_put(struct pci_dev *dev);
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
void pci_bus_add_device(struct pci_dev *dev);
void pci_bus_add_devices(const struct pci_bus *bus);
2.2.4.Driver

RC Core层使用struct pci_driver数据结构描述PCIe设备驱动。PCIe设备和驱动匹配的信息保存到id_table中。pci_register_driver注册PCIe设备驱动,pci_unregister_driver注销PCIe设备驱动。

[include/linux/pci.h]
struct pci_driver {struct list_head	node;const char		*name;/* Must be non-NULL for probe to be called */const struct pci_device_id *id_table;/* New device inserted */int  (*probe)(struct pci_dev *dev, const struct pci_device_id *id);/* Device removed (NULL if not a hot-plug capable driver) */void (*remove)(struct pci_dev *dev);/* Device suspended */int  (*suspend)(struct pci_dev *dev, pm_message_t state);/* Device woken up */int  (*resume)(struct pci_dev *dev);void (*shutdown)(struct pci_dev *dev);/* On PF */int  (*sriov_configure)(struct pci_dev *dev, int num_vfs);/*  */const struct pci_error_handlers *err_handler;......
};
/* pci_register_driver() must be a macro so KBUILD_MODNAME can be expanded */
#define pci_register_driver(driver)		\__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)void pci_unregister_driver(struct pci_driver *dev);

pci_bus_type用于匹配PCIe设备和驱动。

struct bus_type pci_bus_type = {.name		= "pci",.match		= pci_bus_match,.uevent		= pci_uevent,.probe		= pci_device_probe,.remove		= pci_device_remove,.shutdown	= pci_device_shutdown,.dev_groups	= pci_dev_groups,.bus_groups	= pci_bus_groups,.drv_groups	= pci_drv_groups,.pm		= PCI_PM_OPS_PTR,.num_vf		= pci_bus_num_vf,.dma_configure	= pci_dma_configure,
};
2.2.5.设备驱动

不同的PCIe设备,需要不同的PCIe设备驱动。下面列出PCIe桥和NVMe硬盘驱动。

2.2.5.1.桥驱动

如下所示,PCIe桥使用"pcieport"驱动。

[drivers/pci/pcie/portdrv_pci.c]
static const struct pci_device_id port_pci_ids[] = {/* handle any PCI-Express port */{ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0) },/* subtractive decode PCI-to-PCI bridge, class type is 060401h */{ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x01), ~0) },/* handle any Root Complex Event Collector */{ PCI_DEVICE_CLASS(((PCI_CLASS_SYSTEM_RCEC << 8) | 0x00), ~0) },{ },
};
static struct pci_driver pcie_portdriver = {.name		= "pcieport",.id_table	= &port_pci_ids[0],.probe		= pcie_portdrv_probe,.remove		= pcie_portdrv_remove,.shutdown	= pcie_portdrv_remove,.err_handler	= &pcie_portdrv_err_handler,.driver.pm	= PCIE_PORTDRV_PM_OPS,
};
static int __init pcie_portdrv_init(void)
{if (pcie_ports_disabled)return -EACCES;pcie_init_services();dmi_check_system(pcie_portdrv_dmi_table);return pci_register_driver(&pcie_portdriver);
}
device_initcall(pcie_portdrv_init);
2.2.5.2.NVMe驱动

M.2 NVMe硬盘使用下面的驱动。

[drivers/nvme/host/pci.c]
static struct pci_driver nvme_driver = {.name		= "nvme",.id_table	= nvme_id_table,.probe		= nvme_probe,.remove		= nvme_remove,.shutdown	= nvme_shutdown,
#ifdef CONFIG_PM_SLEEP.driver		= {.pm	= &nvme_dev_pm_ops,},
#endif.sriov_configure = pci_sriov_configure_simple,.err_handler	= &nvme_err_handler,
};static int __init nvme_init(void)
{BUILD_BUG_ON(sizeof(struct nvme_create_cq) != 64);BUILD_BUG_ON(sizeof(struct nvme_create_sq) != 64);BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64);BUILD_BUG_ON(IRQ_AFFINITY_MAX_SETS < 2);return pci_register_driver(&nvme_driver);
}
module_init(nvme_init);
module_exit(nvme_exit);

3.EP软件框架

3.1.EP Controller Driver

RK3399 PCIe EP Controller Driverr驱动定义如下所示。

[drivers/pci/controller/pcie-rockchip-ep.c]
static const struct of_device_id rockchip_pcie_ep_of_match[] = {{ .compatible = "rockchip,rk3399-pcie-ep"},{},
};static struct platform_driver rockchip_pcie_ep_driver = {.driver = {.name = "rockchip-pcie-ep",.of_match_table = rockchip_pcie_ep_of_match,},.probe = rockchip_pcie_ep_probe,
};builtin_platform_driver(rockchip_pcie_ep_driver);

3.2.EP Controller Core

3.2.1.EPC Device

EP Controller Core层使用struct pci_epc描述PCIe Endpoint Controller Device。EPC的所有的functions都挂到pci_epf链表上,ops指向了EPC提供的回调函数集合,用于设置EPC的配置空间、设置region、设置和发送中断等,windows保存了EPC的Outbound的地址段,num_windows表示Outbound的地址段的数量,max_functions保存了functions的最大数量。使用pci_epc_createdevm_pci_epc_create函数创建struct pci_epcdevm_pci_epc_destroypci_epc_destroy销毁struct pci_epc

[include/linux/pci-epc.h]
/* struct pci_epc - represents the PCI EPC device */
struct pci_epc {struct device			dev;struct list_head		pci_epf;const struct pci_epc_ops	*ops;struct pci_epc_mem		**windows;struct pci_epc_mem		*mem;unsigned int			num_windows;u8				max_functions;struct config_group		*group;/* mutex to protect against concurrent access of EP controller */struct mutex			lock;unsigned long			function_num_map;struct atomic_notifier_head	notifier;
};#define pci_epc_create(dev, ops)    \__pci_epc_create((dev), (ops), THIS_MODULE)
#define devm_pci_epc_create(dev, ops)    \__devm_pci_epc_create((dev), (ops), THIS_MODULE)
void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc);
void pci_epc_destroy(struct pci_epc *epc);

struct pci_epc_ops如下图所示,这些回调函数很重要,EP Controller Driver必须实现。EPF驱动会调用这些函数配置EPC。

[include/linux/pci-epc.h]
struct pci_epc_ops {int	(*write_header)(struct pci_epc *epc, u8 func_no,struct pci_epf_header *hdr);int	(*set_bar)(struct pci_epc *epc, u8 func_no,struct pci_epf_bar *epf_bar);void	(*clear_bar)(struct pci_epc *epc, u8 func_no,struct pci_epf_bar *epf_bar);int	(*map_addr)(struct pci_epc *epc, u8 func_no,phys_addr_t addr, u64 pci_addr, size_t size);void	(*unmap_addr)(struct pci_epc *epc, u8 func_no,phys_addr_t addr);int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);int	(*get_msi)(struct pci_epc *epc, u8 func_no);int	(*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts,enum pci_barno, u32 offset);int	(*get_msix)(struct pci_epc *epc, u8 func_no);int	(*raise_irq)(struct pci_epc *epc, u8 func_no,enum pci_epc_irq_type type, u16 interrupt_num);int	(*start)(struct pci_epc *epc);void	(*stop)(struct pci_epc *epc);const struct pci_epc_features* (*get_features)(struct pci_epc *epc,u8 func_no);struct module *owner;
};
3.2.2.EPF绑定EPC

每个EP的Function都对应一个struct pci_epf设备,即EPF设备,EPF设备和EPC通过pci_epc_add_epf绑定,通过pci_epc_remove_epf解除绑定。

[include/linux/pci-epc.h]
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf);
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf);
3.2.3.EPC API

下面的接口是对struct pci_epc_ops封装,供EPF驱动调用。

[include/linux/pci-epc.h]
int pci_epc_write_header(struct pci_epc *epc, u8 func_no,struct pci_epf_header *hdr);
int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,struct pci_epf_bar *epf_bar);
void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,struct pci_epf_bar *epf_bar);
int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,phys_addr_t phys_addr,u64 pci_addr, size_t size);
void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,phys_addr_t phys_addr);
int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,enum pci_barno, u32 offset);
int pci_epc_get_msix(struct pci_epc *epc, u8 func_no);
int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,enum pci_epc_irq_type type, u16 interrupt_num);
int pci_epc_start(struct pci_epc *epc);
void pci_epc_stop(struct pci_epc *epc);
const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,u8 func_no);

3.3.EP Function Core

EP Function Core层定义了EPF Driver和EPF Device的数据结构,并提供注册、创建及绑定接口。

3.3.1.EPF Driver

EPF Driver的数据结构为struct pci_epf_driver。当EPF Device和EPC Device绑定后,会回调ops函数以通知EPF Driver,id_table定义EPF Driver和EPF Device匹配的信息。pci_epf_register_driver注册EPF Driver,pci_epf_unregister_driver注销EPF Driver。

[include/linux/pci-epf.h]
struct pci_epf_driver {int	(*probe)(struct pci_epf *epf);int	(*remove)(struct pci_epf *epf);struct device_driver	driver;struct pci_epf_ops	*ops;struct module		*owner;struct list_head	epf_group;const struct pci_epf_device_id	*id_table;
};
struct pci_epf_ops {int	(*bind)(struct pci_epf *epf);void	(*unbind)(struct pci_epf *epf);
};#define pci_epf_register_driver(driver)    \__pci_epf_register_driver((driver), THIS_MODULE)
void pci_epf_unregister_driver(struct pci_epf_driver *driver);
3.3.2.EPF Device

每个EP Function都对应一个EPF Device。EPF Device的数据结构为struct pci_epf_driverheader保存了该EP Function配置空间头信息,bar[6]保存了6个BAR映射的物理地址,msi_interruptsmsix_interrupts分别表示EP Function需要的中断数量,func_no表述EP Function的编号。pci_epf_createpci_epf_destroy创建和销毁EPF Device。

[include/linux/pci-epf.h]
struct pci_epf {struct device		dev;const char		*name;struct pci_epf_header	*header;struct pci_epf_bar	bar[6];u8			msi_interrupts;u16			msix_interrupts;u8			func_no;struct pci_epc		*epc;struct pci_epf_driver	*driver;struct list_head	list;struct notifier_block   nb;/* mutex to protect against concurrent access of pci_epf_ops */struct mutex		lock;
};
struct pci_epf *pci_epf_create(const char *name);
void pci_epf_destroy(struct pci_epf *epf);
3.3.3.EPF Device匹配EPF Driver

pci_epf_bus_type用于匹配EPF Device和EPF Driver。

[drivers/pci/endpoint/pci-epf-core.c]
static struct bus_type pci_epf_bus_type = {.name		= "pci-epf",.match		= pci_epf_device_match,.probe		= pci_epf_device_probe,.remove		= pci_epf_device_remove,
};

3.4.EP Configfs

EP Configfs会在/sys目录下创建文件节点,使用者可以在用户空间通过这些文件节点,配置和创建EPP Device,绑定EPP Device、EPP Driver及EPC Device。

3.5.EP Function Driver。

下面是pci_epf_test的EP Function Driver。

[drivers/pci/endpoint/functions/pci-epf-test.c]
static struct pci_epf_ops ops = {.unbind	= pci_epf_test_unbind,.bind	= pci_epf_test_bind,
};static struct pci_epf_driver test_driver = {.driver.name	= "pci_epf_test",.probe		= pci_epf_test_probe,.id_table	= pci_epf_test_ids,.ops		= &ops,.owner		= THIS_MODULE,
};

参考资料

  1. PCIEXPRESS体系结构导读
  2. PCI Express technology 3.0
  3. PCI Express® Base Specification Revision 5.0 Version 1.0
  4. Rockchip RK3588 TRM
  5. Linux kernel 5.10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/876529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【React】详解 React Hooks 使用规则

文章目录 一、Hooks 的基本原则1. 只在最顶层调用 Hooks2. 只在 React 函数组件和自定义 Hooks 中调用 Hooks 二、常见 Hooks 及其使用规则1. useState2. useEffect3. useContext4. useReducer5. useMemo6. useCallback 三、常见错误及其解决方案1. 在条件语句中调用 Hooks2. 在…

RK3568 Linux 平台开发系列讲解(内核入门篇):从内核的角度看外设芯片的驱动

在嵌入式 Linux 开发中,外设芯片的驱动是实现操作系统与硬件之间交互的关键环节。对于 RK3568 这样的处理器平台,理解如何从内核的角度构建和管理外设芯片的驱动程序至关重要。 1. 外设驱动的基础概念 外设驱动(Device Driver)是操作系统与硬件设备之间的桥梁。它负责控…

机器学习(二十一):错误分析、创造数据和迁移学习

一、错误分析 假设交叉验证集一共有500个数据点&#xff0c;模型拟合结果中&#xff0c;有100个数据点有误。 错误分析就是&#xff0c;手动地分析这100个错误数据&#xff08;或随机选择一些错误数据&#xff09;&#xff0c;根据它们的共同属性、共同特征分类&#xff0c;然…

在QT中使用多线程并发服务器(C++)

什么是多线程并发服务器&#xff1f;在QT里如何使用多线程并发服务器呢&#xff1f; 多线程并发服务器是一种网络服务器设计&#xff0c;它能够同时处理多个客户端的请求。在多线程服务器中&#xff0c;主线程负责监听和接受来自客户端的连接请求&#xff0c;每当有一个新的连…

C++(week13): C++基础: 标准模板库 STL

文章目录 零、标准模板库 STL一、容器 (Container)1.序列式容器(1)vector2.五种遍历10.vector的迭代器失效问题 (2)deque(3)list 2.关联式容器(1)set4.set的查找(2)find() 8.set中存储自定义类型&#xff1a;三种方法 (2)multiset7.multiset的特殊操作&#xff1a;bound系列函数…

【前端 15】Vue生命周期

Vue生命周期 在Vue.js中&#xff0c;了解组件的生命周期对于开发者来说是至关重要的。Vue的生命周期指的是Vue实例从创建到销毁的一系列过程&#xff0c;每个阶段都对应着特定的生命周期钩子&#xff08;或称为生命周期方法&#xff09;&#xff0c;允许我们在不同的时间点加入…

【网络安全】AWS S3 Bucket配置错误导致敏感信息泄露

未经许可&#xff0c;不得转载。 文章目录 前言技术分析正文 前言 AWS&#xff08;Amazon Web Services&#xff09;是亚马逊公司提供的一个安全的云服务平台&#xff0c;旨在为个人、公司和政府机构提供计算能力、存储解决方案、内容交付和其他功能。作为全球领先的云服务提供…

Autodesk Revit v2025 激解锁版下载及安装教程 (三维建模软件)

前言 Revit是欧特克公司知名的三维建模软件&#xff0c;是建筑业BIM体系中使用最广泛的软件之一&#xff0c;其核心功能是三维建筑模型参数化设计、渲染效果图、算量&#xff0c;土建建模、机电建模、用来帮助工程师在施工前精确模拟阶段。 一、下载地址 下载链接&#xff1…

体育赛事中的AI运用

7月24日&#xff0c;国际奥委会&#xff08;IOC&#xff09;举办了新闻发布会&#xff0c;宣布计划在2024年巴黎奥运会上展示一系列创新的人工智能&#xff08;AI&#xff09;技术。这次会议不仅是对即将到来的奥运赛事的预热&#xff0c;也深入探讨了人工智能在体育领域可能带…

快速重装系统

挑选系统 https://d1506.xy58.net/202002/Js_GhostWin7z_x64_2020T.iso WIN11镜像 安装PE启动U盘安装工具 本地安装

【机器学习】深入理解损失函数(Loss Functions)

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入理解损失函数(Loss Functions)什么是损失函数?常见损失函数类型1. 均方误差…

【C++】set的使用

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 &#x1f308;前言&#x1f308;关于set&#x1f525;容量函数emptysize &#x1f525;Modifiersinserteraseclear &#x1f525;Operationsfindcountlower_bound和upper_…

Lesson 51 A pleasant climate

Lesson 51 A pleasant climate 词汇 Greece n. 希腊 Greek a. 希腊的&#xff0c;希腊语 搭配&#xff1a;Greek gift 不怀好意的礼物 例句&#xff1a;他的电脑是不怀好意的礼物。    His computer is a Greek gift. climate n. 气候 长时间&#xff0c;不容易更改的 we…

一键将桌面资料存到d盘的工具,小巧、绿色、免费、免安装

为了提升我们的系统稳定性以及资料的安全性&#xff0c;建议大家将电脑桌面的资料默认路径设置为D盘或其他磁盘&#xff0c;这样不仅会减少系统盘的占用空间&#xff0c;在系统盘出现故障时我们还可以通过pe工具备份桌面的资料。虽然我们也可以通过一些操作来修改桌面文件以及我…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑电动汽车动态拥堵的配电网灵活性资源双层优化调度 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

嵌入式Python、决策树算法、SQLite、Flask、树莓派、机器学习:基于算法自主决策的智能家居系统(代码示例)

项目概述 随着物联网技术的快速发展&#xff0c;智能家居系统越来越普及&#xff0c;成为现代家庭生活的重要组成部分。本文将介绍一个基于Raspberry Pi和Arduino的智能家居算法控制系统的硬件平台。该系统能够通过传感器采集环境数据&#xff0c;并利用机器学习算法进行分析与…

大数据的数据质量有效提升的研究

大数据的数据质量有效提升是一个涉及多个环节和维度的复杂过程。以下是从数据采集、处理、管理到应用等方面&#xff0c;对大数据数据质量有效提升的研究概述&#xff1a; 一、数据采集阶段 明确采集需求&#xff1a;在数据采集前&#xff0c;需明确数据需求&#xff0c;包括…

VMware、Docker - 让虚拟机走主机代理,解决镜像封禁问题

文章目录 虚拟机全局代理配置找到 VMnet8 的 IPv4 地址代理相关配置虚拟机代理配置 Docker 代理配置修改镜像修改 Docker 代理配置 虚拟机全局代理配置 找到 VMnet8 的 IPv4 地址 a&#xff09;打开此电脑&#xff0c;输入 “控制面板”&#xff0c;然后回车. b&#xff09;之…

【计算机毕业设计】850汽车售后服务信息管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【计算机方向】五本“三区水刊”重磅推荐!几乎不拒收,国人发文友好!

本期将为您带来五本计算机SCI 妥妥毕业神刊&#xff01; AUTONOMOUS AGENTS AND MULTI-AGENT SYSTEMS International Journal on Document Analysis and Recognition COMPUTATIONAL INTELLIGENCE IET Biometrics ACM Transactions on Asian and Low-Resource L…