Linux 下的 regulator 子系统

1、简介

  regulator 框架是 Linux 内核中用于管理电压和电流调节器(如 LDO、DCDC 转换器等)的一个子系统。它提供了一个抽象层,使得驱动程序和内核的其他部分可以以一致的方式与调节器进行交互,而无需了解底层硬件的细节。
主要功能包括:

  • 控制电压的启停
  • 调整输出电压
  • 查询当前电压状态
  • 保护系统不受过流或过压的影响

2、设备树中的 regulator

  设备树中常见的有两种 regulator,一种是可变的 regulator,一种是固定的 regulator。

2.1 固定 regulator

  固定 regulator 在 Linux 设备树中的 compatible 为 “regulator-fixed”。固定,顾名思义,该 regulator 不支持电压调节,只支持 enable/disable。

  regulator-fixed 通常是由一个 GPIO 控制了一路 regulator,如下图,GPIO3_C3 控制了 TP6327GS6 电源芯片,输出 MINIPCIE_3V3 电压给到 MINIPCIE 部件。

在这里插入图片描述
对应的设备树节点如下:

	vcc3v3_m2_pcie: vcc3v3-m2-pcie-regulator {compatible = "regulator-fixed";regulator-name = "m2_pcie_3v3";enable-active-high;regulator-min-microvolt = <3300000>;regulator-max-microvolt = <3300000>;gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;pinctrl-0 = <&vcc3v3_m2_pcie_en>;pinctrl-names = "default";startup-delay-us = <200000>;vin-supply = <&vcc5v0_sys>;};

解析如下:

  • regulator-min-microvolt:固定电压(对于 regulator-fixed 来说,min 和 max 一定相同)
  • gpios :控制 regulator 使能的 gpio 引脚(当调用 enable regulator 接口时就是使能该 gpio 引脚)
  • startup-delay-us:启动时间(微秒)
  • enable-active-high:GPIO 极性为高电平有效。如果缺少此属性,则默认为低电平有效。
  • regulator-boot-on:指示该 regulator 在 bootloader/firmware 阶段已经被 enable 了(注意,只能确定 bootloader 阶段,无法确定系统启动后的一个状态)
  • regulator-always-on:该 regulator 永远不应该被禁用,系统一上电就应该使能该 regulator
  • gpio-open-drain:GPIO 为开漏类型。如果缺少此属性,则默认假设为 false
  • vin-supply:该 regulator 输入源

关于 regulator-fixed 详细节点属性,见
Linux/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml

regulator-fixed 对应的驱动文件:drivers/regulator/fixed.c

static const struct regulator_ops fixed_voltage_ops = {
};

可以看到,fixed_voltage_ops 结构为空,不支持调节电压。

2.2 可变 regulator

  可变 regulator,常见的,又可分为 regulator-gpio 和 普通 regualtor。

2.2.1 regulator-gpio

  通常是由 GPIO 控制的 regulator。可以通过一个或多个 GPIO 控制输出多个不同的电压或电流,因此除了开(enable) \ 关(disabled)两种操作外,往往还支持电压或电流的控制。

具体是电压还是电流,是由设备树节点中的 regulator-type 属性决定的。如果没有该属性,默认是电压调节

对应的 Linux 设备树节点如下:

    gpio-regulator {compatible = "regulator-gpio";regulator-name = "mmci-gpio-supply";regulator-min-microvolt = <1800000>;regulator-max-microvolt = <2600000>;regulator-boot-on;enable-gpios = <&gpio0 23 0x4>;gpios = <&gpio0 24 0x4&gpio0 25 0x4>;states = <1800000 0x3>,<2200000 0x2>,<2600000 0x1>,<2900000 0x0>;startup-delay-us = <100000>;enable-active-high;};

解析如下:

  • regulator-min-microvolt:描述该电源输出电压的允许范围最小值 1.8v
  • regulator-max-microvolt:描述该电源输出电压的允许范围最大值 2.6v
  • regulator-boot-on:指示该 regulator 在 bootloader/firmware 阶段已经被 enable 了(注意,只能确定 bootloader 阶段,无法确定系统启动后的一个状态)
  • enable-gpios:用来控制该 regulator 开关的 gpio 引脚
  • gpios:一个或多个 GPIO 引脚数组,用于选择 “states” 中列出的调节器电压/电流
  • states:此 regulator 提供的可用电压/电流,并匹配相应的 GPIO 配置以实现这些电压/电流
  • gpios-states:在不支持在输出模式下读取 GPIO 值的操作系统上(尤其是 Linux),此数组提供从 GPIO 控制器请求 GPIO 引脚时设置的 GPIO 引脚状态(可以理解为设置 gpios 的初始状态)。gpios-states 属性中的元素和 gpios 属性中的元素一一对应
  • startup-delay-us:启动时间(微秒)
  • enable-active-high:GPIO 极性为高电平有效。如果缺少此属性,则默认为低电平有效。

关于 regulator-gpio 详细节点属性,见
Linux/Documentation/devicetree/bindings/regulator/gpio-regulator.yaml

  关于 statesgpios 属性这里详细解释一下,这两个属性是成对出现。regulator-gpio 本质上,是通过一组 GPIO(也就是 gpios 属性中的),来控制不同的电压输出。可提供的电压输出选项(也就是 states 属性中的)。

gpio0_24 电平gpio0_25 电平输出电压
002.9v
012.2v
102.6v
111.8v
2.2.2 普通 regulator
	vdd_cpu: regulator@1c {compatible = "tcs,tcs4525";reg = <0x1c>;fcs,suspend-voltage-selector = <1>;regulator-name = "vdd_cpu";regulator-always-on;regulator-boot-on;regulator-min-microvolt = <800000>;regulator-max-microvolt = <1150000>;regulator-ramp-delay = <2300>;vin-supply = <&vcc5v0_sys>;regulator-state-mem {regulator-off-in-suspend;};};

解析如下:

  • regulator-min-microvolt:描述该电源输出电压的允许范围最小值 0.8v
  • regulator-max-microvolt:描述该电源输出电压的允许范围最大值 1.15v
  • regulator-ramp-delay:改变电压到电源稳定后需要的时间
  • regulator-boot-on:指示该 regulator 在 bootloader/firmware 阶段已经被 enable 了(注意,只能确定 bootloader 阶段,无法确定系统启动后的一个状态)
  • regulator-always-on:该 regulator 永远不应该被禁用,系统一上电就应该使能该 regulator
  • vin-supply:该 regulator 输入源

3、Linux 源码中的 regulator 驱动

3.1 框架

在这里插入图片描述

3.2 machine

  machin 使用 struct regulator_init_data静态的描述 regulator 在板级的硬件连接情况。这些限制通过驱动或 dts 配置,涉及到系统供电安全,因此必须小心,这些配置主要包括:

  1. 用于描述 regulator 在板级的级联关系:前级 regulator(即该 regulator 的输出是另一个 regulator 的输入,简称 supply regulator)和后级 regulator(即该 regulator 的输入是其它 regulator 的输出,简称 consumer regulator)
  2. 利用 struct regulation_constraints 描述 regulator 的物理限制,比如:
    • 输出电压的最大值和最小值(voltage regulator)
    • 输出电流的最大值和最小值(current regulator)
    • 允许的操作(修改电压值、修改电流限制、enable、disable等)
    • 输入电压是多少(当输入是另一个regulator时)
    • 是否不允许关闭(always_on)
    • 是否启动时就要打开(always_on)

涉及到的 Linux 源码文件:Linux/include/linux/regulator/machine.h

/*** struct regulator_init_data - regulator platform initialisation data.** Initialisation constraints, our supply and consumers supplies.** @supply_regulator: Parent regulator.  Specified using the regulator name*                    as it appears in the name field in sysfs, which can*                    be explicitly set using the constraints field 'name'.** @constraints: Constraints.  These must be specified for the regulator to*               be usable.* @num_consumer_supplies: Number of consumer device supplies.* @consumer_supplies: Consumer device supply configuration.** @regulator_init: Callback invoked when the regulator has been registered.* @driver_data: Data passed to regulator_init.*/
struct regulator_init_data {const char *supply_regulator;        /* or NULL for system supply */struct regulation_constraints constraints;int num_consumer_supplies;struct regulator_consumer_supply *consumer_supplies;/* optional regulator machine specific init */int (*regulator_init)(void *driver_data);void *driver_data;	/* core does not touch this */
};/*** struct regulation_constraints - regulator operating constraints.** This struct describes regulator and board/machine specific constraints.** @name: Descriptive name for the constraints, used for display purposes.** @min_uV: Smallest voltage consumers may set.* @max_uV: Largest voltage consumers may set.* @uV_offset: Offset applied to voltages from consumer to compensate for*             voltage drops.** @min_uA: Smallest current consumers may set.* @max_uA: Largest current consumers may set.* @ilim_uA: Maximum input current.* @system_load: Load that isn't captured by any consumer requests.** @over_curr_limits:		Limits for acting on over current.* @over_voltage_limits:	Limits for acting on over voltage.* @under_voltage_limits:	Limits for acting on under voltage.* @temp_limits:		Limits for acting on over temperature.** @max_spread: Max possible spread between coupled regulators* @max_uV_step: Max possible step change in voltage* @valid_modes_mask: Mask of modes which may be configured by consumers.* @valid_ops_mask: Operations which may be performed by consumers.** @always_on: Set if the regulator should never be disabled.* @boot_on: Set if the regulator is enabled when the system is initially*           started.  If the regulator is not enabled by the hardware or*           bootloader then it will be enabled when the constraints are*           applied.* .....* .....*/
struct regulation_constraints {const char *name;/* voltage output range (inclusive) - for voltage control */int min_uV;int max_uV;int uV_offset;/* current output range (inclusive) - for current control */int min_uA;int max_uA;int ilim_uA;int system_load;/* used for coupled regulators */u32 *max_spread;/* used for changing voltage in steps */int max_uV_step;/* valid regulator operating modes for this machine */unsigned int valid_modes_mask;/* valid operations for regulator on this machine */unsigned int valid_ops_mask;/* regulator input voltage - only if supply is another regulator */int input_uV;......
}

3.3 regulator driver

  regulator driver 指的是具体的 regulator 设备的驱动,例如:

  • regulator-gpio 这一类的 regulator 驱动,对应的驱动文件 Linux/drivers/regulator/gpio-regulator.c
  • regulator-fixed 这一类的 regulator 驱动,对应的驱动文件 Linux/drivers/regulator/fixed.c
  • tcs,tcs4525 这种具体的 regulator 驱动,对应的驱动文件 Linux/drivers/regulator/fan53555.c

  regulator drive 要做的事,是操作底层具体的 regulator 硬件寄存器,控制 regulator 输出的电流、电压。同时将控制电压、电流的接口封装,注册、提交给 regulator framework core 层。

  在内核 Linux/kernel/drivers/regulator/dummy.c 文件中构造了一个虚拟的 regulator,给各种 regulator 驱动开发提供的参考。

// SPDX-License-Identifier: GPL-2.0-or-later
/** dummy.c** Copyright 2010 Wolfson Microelectronics PLC.** Author: Mark Brown <broonie@opensource.wolfsonmicro.com>** This is useful for systems with mixed controllable and* non-controllable regulators, as well as for allowing testing on* systems with no controllable regulators.*/#include <linux/err.h>
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>#include "dummy.h"struct regulator_dev *dummy_regulator_rdev;/*  *	提供 machine 层的 regulator_init_data 资源*  通常在 regulator 驱动中,regulator_init_data 资源是通过设备树解析出来的。*  调用 of_get_regulator_init_data 设备树接口,而不是像下面这样直接在驱动中固定*  解析出的 machine 信息保存在 struct regulator_config 结构中*  通过调用 devm_regulator_register 系统接口,将接口注册进 regulator framework core 中*/
static const struct regulator_init_data dummy_initdata = {.constraints = {.always_on = 1,},
};/** 封装具体的控制 regulator 电压、电流的函数接口(通过操作一些 regulaor 硬件寄存器)* 存放在 struct regulator_desc 结构中* 通过调用 devm_regulator_register 系统接口,将接口注册进 regulator framework core 中*/
static const struct regulator_ops dummy_ops;static const struct regulator_desc dummy_desc = {.name = "regulator-dummy",.id = -1,.type = REGULATOR_VOLTAGE,.owner = THIS_MODULE,.ops = &dummy_ops,
};static int dummy_regulator_probe(struct platform_device *pdev)
{struct regulator_config config = { };int ret;config.dev = &pdev->dev;config.init_data = &dummy_initdata;/* * 向 regulator framework core 注册接口* 函数入参 struct regulator_desc、struct regulator_config*/dummy_regulator_rdev = devm_regulator_register(&pdev->dev, &dummy_desc,&config);if (IS_ERR(dummy_regulator_rdev)) {ret = PTR_ERR(dummy_regulator_rdev);pr_err("Failed to register regulator: %d\n", ret);return ret;}return 0;
}static struct platform_driver dummy_regulator_driver = {.probe		= dummy_regulator_probe,.driver		= {.name		= "reg-dummy",.probe_type	= PROBE_PREFER_ASYNCHRONOUS,},
};static struct platform_device *dummy_pdev;void __init regulator_dummy_init(void)
{int ret;dummy_pdev = platform_device_alloc("reg-dummy", -1);if (!dummy_pdev) {pr_err("Failed to allocate dummy regulator device\n");return;}ret = platform_device_add(dummy_pdev);if (ret != 0) {pr_err("Failed to register dummy regulator device: %d\n", ret);platform_device_put(dummy_pdev);return;}ret = platform_driver_register(&dummy_regulator_driver);if (ret != 0) {pr_err("Failed to register dummy regulator driver: %d\n", ret);platform_device_unregister(dummy_pdev);}
}

3.4 regulator framework core

  regulator framework core 屏蔽了底层各种 regulaor 硬件的差异,对上面的 regulator consumer 提供统一的控制类接口。并提供接口给内核中其他的 consumer(使用当前 regulator 设备的驱动),并以 sysfs 的形式,向用户空间提供接口。

  regulator framework core 主要涉及的文件是:Linux/drivers/regulator/core.c

  该文件涉及了 regulator framework core 层接口的具体实现。例如,实现 regulator driver 层注册 regulator 的接口: devm_regulator_register 等。

3.5 regulator consumer

  regulator consumer 抽象出 regulator 设备(struct regulator),并提供 regulator 操作相关的接口。包括:

  • regulator_get/regulator_put
  • regulator_enable/regulator_disable
  • regulator_set_voltage/regulator_get_voltage 等

  以调节 CPU 电压为例:

	vdd_cpu: regulator@1c {compatible = "tcs,tcs4525";reg = <0x1c>;fcs,suspend-voltage-selector = <1>;regulator-name = "vdd_cpu";regulator-always-on;regulator-boot-on;regulator-min-microvolt = <800000>;regulator-max-microvolt = <1150000>;regulator-ramp-delay = <2300>;vin-supply = <&vcc5v0_sys>;regulator-state-mem {regulator-off-in-suspend;};};&cpu0 {cpu-supply = <&vdd_cpu>;
};&cpu1 {cpu-supply = <&vdd_cpu>;
};&cpu2 {cpu-supply = <&vdd_cpu>;
};&cpu3 {cpu-supply = <&vdd_cpu>;
};

consumer 代码调用流程:

dt_cpufreq_early_init--> dev_pm_opp_set_regulators--> regulator_get_optional

通过解析 CPU 设备树节点 cpu-supply 属性,调用 regulator_get_optional 找到 CPU 对应的 regulator。

struct regulator * regulator_get_optional(struct device * dev, const char * id);

Parameters

  • struct device * dev
    • device for regulator “consumer”
  • const char * id
    • Supply name or regulator ID

获取到对应的 regulator 结构后,会调用 regulator_set_voltage 设置具体的 CPU 电压

static int _set_opp_voltage(struct device *dev, struct regulator *reg,struct dev_pm_opp_supply *supply)
{int ret;/* Regulator not available for device */if (IS_ERR(reg)) {dev_dbg(dev, "%s: regulator not available: %ld\n", __func__,PTR_ERR(reg));return 0;}dev_dbg(dev, "%s: voltages (mV): %lu %lu %lu\n", __func__,supply->u_volt_min, supply->u_volt, supply->u_volt_max);ret = regulator_set_voltage_triplet(reg, supply->u_volt_min,supply->u_volt, supply->u_volt_max);if (ret)dev_err(dev, "%s: failed to set voltage (%lu %lu %lu mV): %d\n",__func__, supply->u_volt_min, supply->u_volt,supply->u_volt_max, ret);return ret;
}

4、关于电压操作的两种方式

Linux kernel 抽象了两种电压操作的方法:

  • 直接操作电压
  • 以 selector 的形式

4.1 直接操作电压

  对应 struct regulator_ops 中的如下回调函数:

 /* enumerate supported voltages */int (*list_voltage) (struct regulator_dev *, unsigned selector);/* get/set regulator voltage */int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV,unsigned *selector);int (*get_voltage) (struct regulator_dev *);
  • set_voltage, 用于将电压设置为 min_uV 和 max_uV 范围内、和 min_uV 最接近的电压。该接口可以返回一个 selector 参数,用于告知调用者,实际的电压值对应的索引
  • get_voltage,用于返回当前的真实电压值
  • list_voltage,以 selector 为参数,获取 selector 对应的真实电压值

  这里的 selector 可以理解为,电压值对应的索引。这个值的类型、计算方法,每个 regulator 驱动都可能不同(也可以里理解为,只有 regulator 驱动本人才知道 selector 是啥)。以 regulator-gpio 驱动为例:

static int gpio_regulator_set_voltage(struct regulator_dev *dev,int min_uV, int max_uV,unsigned *selector)
{struct gpio_regulator_data *data = rdev_get_drvdata(dev);int ptr, target = 0, state, best_val = INT_MAX;for (ptr = 0; ptr < data->nr_states; ptr++)if (data->states[ptr].value < best_val &&data->states[ptr].value >= min_uV &&data->states[ptr].value <= max_uV) {target = data->states[ptr].gpios;best_val = data->states[ptr].value;/* 从这里也可以看到,返回的 selector 就是将要设置的电压对应的设备树节点 states 中的电压编号 */if (selector)*selector = ptr;}if (best_val == INT_MAX)return -EINVAL;for (ptr = 0; ptr < data->nr_gpios; ptr++) {state = (target & (1 << ptr)) >> ptr;gpiod_set_value_cansleep(data->gpiods[ptr], state);}data->state = target;return 0;
}

4.2 以 selector 的形式

  regulator driver 以 selector 的形式,反映电压值。selector 是一个从 0 开始的整数,driver 提供如下的接口:

int (*map_voltage)(struct regulator_dev *, int min_uV, int max_uV);
int (*set_voltage_sel) (struct regulator_dev *, unsigned selector);
int (*get_voltage_sel) (struct regulator_dev *);
  • map_voltage,是和 list_voltage 相对的接口,用于将电压范围 map 成一个 selector(这个电压范围对应的一个索引)
  • set_voltage_sel,以 selector 的形式,设置电压,函数入参为 selector
  • get_voltage_sel,以 selector 的形式,读取电压,返回值为 selector

以瑞芯微 rk809 regulator 驱动为例:

/*** regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges** @rdev: Regulator to operate on* @min_uV: Lower bound for voltage* @max_uV: Upper bound for voltage** Drivers providing linear_ranges in their descriptor can use this as* their map_voltage() callback.*/
int regulator_map_voltage_linear_range(struct regulator_dev *rdev,int min_uV, int max_uV)
{const struct linear_range *range;int ret = -EINVAL;unsigned int sel;bool found;int voltage, i;if (!rdev->desc->n_linear_ranges) {BUG_ON(!rdev->desc->n_linear_ranges);return -EINVAL;}for (i = 0; i < rdev->desc->n_linear_ranges; i++) {range = &rdev->desc->linear_ranges[i];ret = linear_range_get_selector_high(range, min_uV, &sel,&found);if (ret)continue;ret = sel;/** Map back into a voltage to verify we're still in bounds.* If we are not, then continue checking rest of the ranges.*/voltage = rdev->desc->ops->list_voltage(rdev, sel);if (voltage >= min_uV && voltage <= max_uV)break;}if (i == rdev->desc->n_linear_ranges)return -EINVAL;return ret;
}

  regulator 的输出电压通过内部的寄存器值(selector 或 index)控制的,寄存器值与输出电压之间有一个固定的映射关系。这个映射关系可以用以下公式表示:
V o u t = V m i n + s e l e c t o r × u V s t e p V_{out}=V_{min}+selector×uV_{step} Vout=Vmin+selector×uVstep
其中:

  • V_ o u t {out} out 是当前输出电压
  • V_ m i n {min} min 是调节器支持的最低输出电压
  • uV_ s t e p {step} step 是调节电的压步长
  • selector 是一个整数(从 0 开始),对应电压级别。

硬件只支持离散的 selector 值,因此电压只能按照 uV_step 的倍数变化。

例如:

/*** struct linear_range - table of selector - value pairs** Define a lookup-table for range of values. Intended to help when looking* for a register value matching certaing physical measure (like voltage).* Usable when increment of one in register always results a constant increment* of the physical measure (like voltage).** @min:  Lowest value in range* @min_sel: Lowest selector for range* @max_sel: Highest selector for range* @step: Value step size*/
struct linear_range {unsigned int min;unsigned int min_sel;unsigned int max_sel;unsigned int step;
};static const struct regulator_linear_range my_ranges[] = {{.min_uV = 800000,.min_sel = 0,.max_sel = 15,.uV_step = 25000,},
};

在这种定义下:

  • selector = 0 → 800,000 μV
  • selector = 1 → 825,000 μV
  • selector = 15 → 1,175,000 μV

4.3 总结

  以上两种方式,regulator driver 可以根据实际情况,选择一种实现方式。

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

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

相关文章

12345政务热线系统:接诉即办,赋能智慧城市治理

一、12345热线&#xff1a;民情直通车&#xff0c;治理新引擎 “12345”政务热线是党委政府了解社情民意、解决群众合理诉求、倾听批评建议、改进工作作风的重要渠道。当前&#xff0c;全国各城市已基本建成12345政务服务热线体系&#xff0c;形成“接诉即办”的高效响应机制。…

【SpringBoot核心】Spring Boot + MyBatis 深度整合与最佳实践

目录 引言Spring Boot 基础回顾MyBatis 核心概念解析Spring Boot 整合 MyBatisMyBatis 高级特性Spring Boot + MyBatis 最佳实践性能优化与扩展实战案例:电商系统开发常见问题与解决方案总结与展望1. 引言 1.1 技术背景与现状 在现代企业级应用开发中,数据持久化是一个核心…

力扣第77题-组合-力扣第78题-子集

力扣链接:77. 组合 - 力扣&#xff08;LeetCode&#xff09; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3…

嵌入式MTD设备与Flash管理解析

理解MTD是嵌入式系统中处理Flash存储的关键一步&#xff01;我来帮你梳理清楚&#xff1a; MTD 是什么&#xff1f; MTD 是 Memory Technology Device 的缩写&#xff0c;中文常译为内存技术设备。它是 Linux 内核及其衍生系统&#xff08;如嵌入式 Linux&#xff09;中用于管…

基于 GEE 利用 Sentinel-2 数据计算并下载植被指数数据

目录 1 植被指数 2 完整代码 3 运行结果 1 植被指数 植被指数全名NDVI归一化差值植被指数GNDVI绿色归一化差值植被指数EVI增强植被指数EVI2双波段增强植被指数DVI差值植被指数GDVI绿色差植被值指数RVI比值植被指数SAVI土壤调整植被指数OSAVI优化土壤调整植被指数MSAVI修改…

python基础23(2025.6.29)分布式爬虫(增量式爬虫去重)redis应用_(未完成!)

本次写一个爬取网易新闻的案例。因为redis能处理高并发&#xff0c;存储数据也可以&#xff0c;故不用mysql。而且新闻网站容易更新很多&#xff0c;而mysql只能持久化存储。 import scrapy import re import json import redis # 用它来去除重复, 记录访问过的urlclass Wang…

Springboot 集成 SpringState 状态机

Springboot 集成 SpringState 状态机 1.SpringState 简介2.状态机示例2.1 项目结构和依赖包2.2 定义事件类和状态类2.3 Spring 事件监听器2.4 状态机持久化类2.4.1 Redis 状态机持久化容器2.4.2 Redis 配置2.4.3 状态机监听器 2.5 装机器容器2.6 状态机事件发送器2.7 状态机配置…

实战四:基于PyTorch实现猫狗分类的web应用【2/3】

​一、需求描述 实战四分为三部分来实现&#xff0c;第二部分是基于PyTorch的猫狗图像可视化训练的教程&#xff0c;实现了一个完整的猫狗分类模型训练流程&#xff0c;使用预训练的ResNet50模型进行迁移学习&#xff0c;并通过SwanLab进行实验跟踪。 效果图 ​二、实现思路 …

对比几个测试云的一些速度

最近被hosting vps主机的速度给困扰了&#xff0c;干脆放下手中的活 测试下 test.php放在网站根目录即可 代码如下&#xff1a; <?php /*** 最终版服务器性能测试工具* 测试项目&#xff1a;CPU运算性能、内存读写速度、硬盘IO速度、网络下载速度*/// 配置参数&#xff…

UE5 Grid3D 学习笔记

一、Neighbor Grid 3D 的核心作用 NeighborGrid3D 是一种基于位置的哈希查找结构&#xff0c;将粒子按空间位置划分到网格单元&#xff08;Cell&#xff09;中&#xff0c;实现快速邻近查询&#xff1a; 空间划分&#xff1a;将模拟空间划分为多个三维网格单元&#xff08;Cel…

Spring AI ——在springboot应用中实现基本聊天功能

文章目录 前言测试环境项目构建依赖引入指定openai 相关配置基于 application.yml 配置 Open AI 属性application.yml编写测试类测试请求基于读取后配置请求编写测试接口测试效果展示流式输出前言 AI 技术越来越火爆,作为Java开发人员也不能拖了后腿。 前段时间使用LangChain…

条件概率:不确定性决策的基石

条件概率是概率论中的核心概念&#xff0c;用于描述在已知某一事件发生的条件下&#xff0c;另一事件发生的概率。它量化了事件之间的关联性&#xff0c;是贝叶斯推理、统计建模和机器学习的基础。 本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术…

搭建Flink分布式集群

1. 基础环境&#xff1a; 1.1 安装JDK 本次使用 jdk-11.0.26_linux-x64_bin.tar.gz 解压缩 tar -zxvf jdk-11.0.26_linux-x64_bin.tar.gz -C /usr/local/java/ 配置环境变量&#xff1a; vi /etc/profileJAVA_HOME/usr/local/java/jdk-11.0.26 CLASSPATH.:${JAVA_HOME}/li…

基于ssm校园综合服务系统微信小程序源码数据库文档

摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;校园综合服务被用户普遍使用&#xff0c;为方便用户能够可…

桌面小屏幕实战课程:DesktopScreen 17 HTTPS

飞书文档http://https://x509p6c8to.feishu.cn/docx/doxcn8qjiNXmw2r3vBEdc7XCBCh 源码参考&#xff1a; /home/kemp/work/esp/esp-idf/examples/protocols/https_request 源码下载方式参考&#xff1a; 源码下载方式 获取网站ca证书 openssl s_client -showcerts -connec…

uniapp上传gitee

右键点击项目&#xff0c;选择git提交&#xff0c;会弹出这样的弹窗 在Message输入框里面输入更新的内容&#xff0c;选择更新过的文件&#xff0c;然后点击commit 然后点击push 后面会让你填写gitee的用户名和密码 用户名就是邮箱 密码就是登录gitee的密码

重写(Override)与重载(Overload)深度解析

在Java面向对象编程中&#xff0c;多态性是一个核心概念&#xff0c;它允许我们以统一的方式处理不同类型的对象。而实现多态性的两种重要机制便是方法的“重写”&#xff08;Override&#xff09;与“重载”&#xff08;Overload&#xff09;。透彻理解这两者之间的区别与联系…

Go 语言中操作 SQLite

sqlite以其无需安装和配置&#xff1a;直接使用数据库文件&#xff0c;无需启动独立的数据库服务进程。 单文件存储&#xff1a;整个数据库&#xff08;包括表、索引、数据等&#xff09;存储在单个跨平台文件中&#xff0c;便于迁移和备份。 在应对的小型应用软件中.有着不可…

【硬核数学】2.3 AI的“想象力”:概率深度学习与生成模型《从零构建机器学习、深度学习到LLM的数学认知》

欢迎来到本系列的第八篇文章。在前七章中&#xff0c;我们已经构建了一个强大的深度学习工具箱&#xff1a;我们用张量来处理高维数据&#xff0c;用反向传播来高效地计算梯度&#xff0c;用梯度下降来优化模型参数。我们训练出的模型在分类、回归等任务上表现出色。 但它们有…

华为云Flexus+DeepSeek征文|Dify平台开发搭建口腔牙科24小时在线问诊系统(AI知识库系统)

引言&#xff1a;为什么需要口腔牙科24小时在线问诊系统&#xff1f; 在口腔医疗领域&#xff0c;“时间”是患者最敏感的需求之一——深夜牙齿突发疼痛、周末想提前了解治疗方案、异地患者无法及时到院……传统“工作时间在线”的咨询模式已无法满足用户需求。同时&#xff0…