Linux 内核学习(2) --- regulator 框架

news2024/11/23 2:31:50

目录

      • Regulator 介绍
      • Regulator provider 注册
        • struct regulator_desc
        • struct regualtor_config
        • DTS 配置和解析
        • On BoardConfig 配置
        • regulator_ops
        • 总结
      • Regulator Consumer 使用
        • struct regulator 获取
        • regulator 操作
        • 使用Multi Regulator
      • 参考博客

Regulator 介绍

Regulator 指的是稳定器(调压器),有电压稳定器及电流稳定器两种,能够自动维持恒定电流或者电压,
其中,电压稳定器 voltage regulator 在电路中比较常见。
从设备驱动的角度来看,regulator 的控制比较简单,主要有 enable/disable/ 输出电压或电流大小的控制。
Linux利用 regulator framework 对 regulator 进行管理和控制。

regulator_framework
由调节器供电的设备被称为消费者(regualtor consumer)。它们消耗调节器提供的电力。大多数调节器可以启用和禁用他们的输出,一些也可以控制他们的输出电压或电流。

Linux regulator 也遵循 provider,framwork,consumer 体系,regulator provider 向系统注册称为 regulator device,并提供它们硬件参数和对应的操作接口函数集合,regulator framework 负责管理系统中的 regulator 设置并提供统一的 consumer 接口,regulator consumer 使用统一的 regulator_get() 等函数获取 compatible 对应的 regulator,并用 regulator_enable() regulator_disbale() 和可选的 regulator_set_voltage 操作 regulator

Linux regulator framework 的主要目的:提供标准的内核接口,控制系统的 voltage/current regulators ,并提供相应的开关、电压/电流设置的机制。

在系统运行的过程中,根据具体的需要动态改变 regulators 的输出,从而达到省电的目的。在系统中如果配错 Regulator 是比较危险的,可能会造成硬件器件的损坏。因此,需要在 regulator framework 中对电流或者电压的大小做强制限定,并且不能被 Regulator 的 consumer 或者 provider 更改。

硬件上提供这些物理调节电压和电流的芯片称为 电源管理集成芯片(PMIC)
PMIC
Linux Regualtor framework 被设计用于开关和控制电压和电流调节器,主要主要分为下面的流程:

  1. Regulator provider 的 register
  2. Regulator consumer 的获取和操作
  3. device tree 的配置和解析的接口
  4. user interface sysfs interface

Regulator provider 注册

Regulator 向内核注册的核心函数如下,注册的参数中包含 struct regulator_descstruct regulator_config 两个主要的结构
相对应的,也存在 regulator_unregister 函数,当模块卸载的时候使用该函数

// include/linux/regulator/driver.h
// drivers/regulator/core.c
struct regulator_dev * regulator_register(const struct regulator_desc *regulator_desc,
		   const struct regulator_config *cfg)
void regulator_unregister(struct regulator_dev *rdev)

现在主要分析注册到 regulator_register 要用到的两个主要结构

struct regulator_desc

struct regulator_desc 的定义如下所示:

struct regulator_desc {
	// regulator name
	const char *name;
	const char *supply_name;

	// 保存了用于识别 devicetree 中的 regulator name 
	const char *of_match;
	const char *regulators_node;
	int (*of_parse_cb)(struct device_node *,
			    const struct regulator_desc *,
			    struct regulator_config *);

	int id;
	unsigned int continuous_voltage_range:1;
	
	// 表示该调节器可用的选择器数量。它表示调节器能输出的值的数量。输出电压固定时,n_voltage 应设为 1。
	unsigned n_voltages;
	
	// regulator 的操作函数
	const struct regulator_ops *ops;
	// regulator interrupt name
	int irq;
	// 指示调节器是电压调节器还是电流调节器。它可以是 REGULATOR_VOLTAGE 或 REGULATOR_CURRENT
	enum regulator_type type;
	struct module *owner;

    // 表示该稳压器能提供的最小电压值。它是由最低的选择器给出的电压。
	unsigned int min_uV;
	// 表示每个选择器增加的电压。
	unsigned int uV_step;
	unsigned int linear_min_sel;
	int fixed_uV;
	unsigned int ramp_delay;
	int min_dropout_uV;
    .....
}

主要参数的含义如下:

name含义
nameregulator name
idregulator 的数字标志符
owner代表提供调节器的模块。将该字段设置为 THIS_MODULE
type指示调节器是电压调节器还是电流调节器,它可以是 REGULATOR_VOLTAGE 或 REGULATOR_CURRENT
n_voltage表示该调节器可用的选择器数量。它表示调节器能输出的值的数量。输出电压固定时,n_voltage 应设为 1
min_uV表示该稳压器能提供的最小电压值。它是由最低的选择器给出的电压
uV_step表示每个选择器增加的电压
opsops表示调节器操作表。它是一个指向调节器可以支持的一组操作回调的结构
min_uVregualtor 的中断号
struct regualtor_config
struct regulator_config {
   struct device *dev;
   const struct regulator_init_data *init_data;
   void *driver_data;
   struct device_node *of_node;
   struct regmap *regmap;

   bool ena_gpio_initialized;
   int ena_gpio;
   unsigned int ena_gpio_invert:1;
   unsigned int ena_gpio_flags;
};

struct regulator_init_data {
   const char *supply_regulator;        /* or NULL for system supply */

   // regulator 的限制或者硬件特性,
   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 */
};

regulator_configs 相关参数的含义如下:

Name说明
dev表示调节器所属的 struct device 结构
init_data是结构中最重要的字段,因为它包含一个包含 regulation_constraints 的元素
driver_data表示持有的 regulator 的私有数据,可以通过 consumer 传递

regulator_configs 包含了 const struct regulator_init_data *init_data 这个关键的结构,其余是 reg 和 gpio 的定义
regulator_init_data中各个结构的含义如下:

struct regulation_constraints {
	const char *name;
	int min_uV;
	int max_uV;

	int uV_offset;
	int min_uA;
	int max_uA;
	int ilim_uA;

	int system_load;
	unsigned int valid_modes_mask;
	unsigned int valid_ops_mask;
	int input_uV;
	/* regulator suspend states for global PMIC STANDBY/HIBERNATE */
	struct regulator_state state_disk;
	struct regulator_state state_mem;
	struct regulator_state state_standby;
	suspend_state_t initial_state; /* suspend state to set at init */

	// 启动时设置的模式
	unsigned int initial_mode;
    .....

regulation_constraints 中各个参数的含义如下:

Name说明
min_uV, min_uA, max_uA 和 max_uV是用户可以设置的最小电压/电流值
uV_offset 是应用于电压从消费者补偿电压下降的偏移量
valid_modes_mask 和 valid_ops_mask 分别是模式和操作的掩码,可以由消费者配置/执行
always_on应该被设置, 如果调节器不能被禁用
boot_on应该被设置如果在系统初始启动时启用了调节器。如果调节器没有被硬件或引导加载程序启用,那么它将在应用约束时启用
name是用于显示目的的约束的描述性名称
apply_uV在初始化时应用电压约束
input_uV表示该调节器由另一个调节器提供时的输入电压
state_disk, state_mem 和 state_standby定义了当系统在磁盘模式、mem模式或备用模式下挂起时调节器的状态
initial_state表示默认设置挂起状态
initial_mode是在启动时设置的模式

struct regulation_constraints 结构是 init data 的一部分。
这可以用以下事实来解释: 在调节器初始化时,它的约束直接应用于它,远远早于任何消费者可以使用它

DTS 配置和解析

struct regulation_constraintsinit_data 中的成员,都可以从 device-tree 中读取并且配置好
下面给出一个参考配置的 DTS 节点:

// 以 pmic is16271a 作为参考
isl6271a@3c {
  compatible = "isl6271a";
  reg = <0x3c>;
  interrupts = <0 86 0x4>;

  /* supposing our regulator is powered by another regulator */
  in-v1-supply = <&some_reg>;
  [...]

  regulators {
    reg1: core_buck {
      regulator-name = "Core Buck";
      regulator-min-microvolt = <850000>;
      regulator-max-microvolt = <1600000>;
    };

    reg2: ldo1 {
      regulator-name = "LDO1";
      regulator-min-microvolt = <1100000>;
      regulator-max-microvolt = <1100000>;
      regulator-always-on;
    };

    reg3: ldo2 {
      regulator-name = "LDO2";
      regulator-min-microvolt = <1300000>;
      regulator-max-microvolt = <1300000>;
      regulator-always-on;
    };
  };
};

DTS 中的每个 PMIC 节点都应该有一个名为 regulators 的子节点,在这个子节点中,我们必须声明PMIC提供的每个调节器为专用子节点。
PMIC的每个调节器都被定义为 regulators 节点的子节点,而 regulators 节点又是 DTS 中 PMIC 节点的子节点。

在 DTS PMIC 中的 regulators 的子节点中可以定义一些标准化的属性

  1. regulator-name: 这是一个字符串,用作调节器输出的描述性名称。
  2. regulator-min-microvolt: 这是用户可以设定的最小电压。
  3. regulator-max-microvolt: 这是用户可设定的最大电压。
  4. regulator-microvolt-offset: 这是施加在电压上以补偿电压下降的偏移量。
  5. regulator-min-microamp: 这是用户可以设定的最小电流。
  6. regulator-max-microamp: 这是用户可以设定的最大电流。
  7. regulator-always-on: 这是一个布尔值,表示不应该禁用调节器。
  8. regulator-boot-on: 这是一个bootloader/firmware 阶段使能的调节器。
  9. <name>-supply: 这是一个指向父供应/调节节点的phandle。
  10. regulator-ramp-delay: 这是调节器的斜坡延迟(用uV/uS表示)

为了提取从 dts 内部传递的 init 数据,我们需要引入一个新的数据类型,struct of_regulator_match,,它的结构如下:

struct of_regulator_match {
	const char *name;
	void *driver_data;
	struct regulator_init_data *init_data;
	struct device_node *of_node;
	const struct regulator_desc *desc;
};

同时内核中还有一个同名的函数 of_regulator_match(),regulators 子节点作为参数,
该函数将遍历每个调节器设备节点,并为每个设备构建一个 struct regulator_init_data 结构体, 这里匹配方法实际就是通过名称来匹配的:

int of_regulator_match(struct device *dev, struct device_node *node,
		       struct of_regulator_match *matches,
		       unsigned int num_matches)

比如在下面的 ab3100.c 中,就使用了 of_regualtor_match 来匹配当前的 regulators 节点,
通过 of_regualtor_match 函数直接 填充了 of_regulator_match 的 struct regulator_init_data 指针 init_data

再以 struct regulator_init_data 指针 init_data 向平台注册:

// ab3100.c 中的regulator 注册方法
static struct of_regulator_match ab3100_regulator_matches[] = {
	{ .name = "ab3100_ldo_a", .driver_data = (void *) AB3100_LDO_A, },
	{ .name = "ab3100_ldo_c", .driver_data = (void *) AB3100_LDO_C, },
	.....
};

if (np) {
    // 传入当前的节点 np, 和 of_regulator_match 结构
    // 如果两者相匹配,就会初始化 init_data
	err = of_regulator_match(&pdev->dev, np,
				 ab3100_regulator_matches,
				 ARRAY_SIZE(ab3100_regulator_matches));
	if (err < 0) {
		dev_err(&pdev->dev,"Error parsing regulator init data: %d\n", err);
		return err;
	}
	return ab3100_regulator_of_probe(pdev, np);
}

static int ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
{
	int err, i;
    
	.....

	for (i = 0; i < ARRAY_SIZE(ab3100_regulator_matches); i++) {
        // 将init_data 作为参数 相 regualtor framework 进行注册
        // 注意使用了 ab3100_regulator_matches[i].init_data 作为参数
        // 将 driver_data 作为私有参数
		err = ab3100_regulator_register(
			pdev, NULL, ab3100_regulator_matches[i].init_data,
			ab3100_regulator_matches[i].of_node,
			(unsigned long)ab3100_regulator_matches[i].driver_data);
		if (err) {
			ab3100_regulators_remove(pdev);
			return err;
		}
	}

	return 0;
}
On BoardConfig 配置

这种方式 legacy 的方法,从驱动程序或板级文件中定义约束数组,并将其用作平台数据的一部分:

// 定义 regulator_init_data 结构
static const struct regulator_init_data arizona_ldo1_dvfs = {
	.constraints = {
		.min_uV = 1200000,
		.max_uV = 1800000,
		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
				  REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies = 1,
};


	switch (arizona->type) {
	case WM5102:
	case WM8997:
	case WM8998:
	case WM1814:
		desc = &arizona_ldo1_hc;
		ldo1->init_data = arizona_ldo1_dvfs;

    ....
    }

	config.init_data = &ldo1->init_data;

    // 以 config.init_data 作为参数,注册 regulator
	ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
regulator_ops

regulator_desc 结构中包含一个 const struct regulator_ops *ops; 表示 regulator 的硬件操作接口:

    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 (*map_voltage)(struct regulator_dev *, int min_uV, int max_uV);
	int (*set_voltage_sel) (struct regulator_dev *, unsigned selector);
	int (*get_voltage) (struct regulator_dev *);
	int (*get_voltage_sel) (struct regulator_dev *);
    ......

   // 回调名称很好地解释了它们的作用, 对于这些回调函数,您必须在调节器的约束valid_ops_mask或valid_modes_mask中启用适当的掩码,然后消费者才能使用它们。  
   // 可用的操作掩码标志在 include/linux/regulator/machine.h 中定义。
总结

regulator_provider 注册的一般步骤如下:

  1. 为PMIC提供的所有调节器定义一个 struct regulator_desc 对象数组,定义一个有效的 struct regulator_ops,以链接到适当的 regulator_desc,所有的 regulator_ops 都可以是相同的,假设它们都支持相同的操作。

  2. 从平台数据(dts node 或者 boarconfig)中获取适当的 struct regulator_init_data 结构体(其中必须已经包含有效的 struct regulator_constraints 结构体,或者从DTS Node 中构建一个 struct regulator_constraints 结构体,以便构建一个新的 struct regulator_init_data 对象

  3. 使用前面的 struct regulator_init_data 来设置 struct regulator_config 结构体。如果驱动程序支持 DTS,你可以让 regulator_config.of_node 指向用于提取调节器属性的节点

  4. regulator_register() 或者 devm_regulator_register())将调节器注册到regulator framework ,并给出之前的 struct regulator_desc struct regulator_config 作为参数。

Regulator Consumer 使用

Regulator consumer 的接口定义在 include/linux/regulator/consumer.h
常用的接口如下:

/* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev,const char *id);
struct regulator *__must_check devm_regulator_get(struct device *dev, const char *id);

int __must_check regulator_enable(struct regulator *regulator);
int regulator_disable(struct regulator *regulator);                       

int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_get_voltage(struct regulator *regulator);

使用比较简单,一般的使用方法如下:

// 定义一个 strutc regulator 结构
// 使用 regulator_get 获取
int ret;
struct regulator *reg;
const char *supply = "vdd1";
int min_uV, max_uV;

reg = regulator_get(dev, supply);

其中的关键结构就是 struct regulator,定义如下:

struct regulator {
	struct device *dev;
	struct list_head list;
	unsigned int always_on:1;
	unsigned int bypass:1;
	int uA_load;
	int min_uV;
	int max_uV;
	char *supply_name;
	struct device_attribute dev_attr;
	struct regulator_dev *rdev;
	struct dentry *debugfs;
};
struct regulator 获取

获取 struct regulator 的 函数主要为:

struct regulator *__must_check regulator_get(struct device *dev, const char *id);
struct regulator *__must_check devm_regulator_get(struct device *dev,  const char *id);

传入的 驱动设备的 dev 类型和 Regulator name 的字符串指针,Regulatr framework 通过 DTS 注册进来的 regulator 设备根据名称进行查找,
关联到正确的操作函数,返回 struct regulator 结构

释放 regulator 的操作函数是:

void regulator_put(struct regulator *regulator);

在调用这个函数之前,驱动程序应该确保对这个调节器源的所有 regulator_enable() 调用都被 regulator_disable() 调用平衡

regulator 操作

Regulator 的操作函数如下:

int __must_check regulator_enable(struct regulator *regulator);
int regulator_disable(struct regulator *regulator)

通过 regulator_enable 和 regulator_disable 函数来开启或者禁用电源

对于共享调节器,regulator_disable() 实际上只在启用的引用计数为零时禁用调节器。
也就是说,你可以在紧急情况下强制禁用。例如,通过调用 regulator_force_disable()

每个函数实际上都是对 注册时的regulator_ops 操作的包装
例如,regulator_set_voltage() 在内部调用 regulator_ops.set_voltage 在检查了相应的掩码后允许设置此操作。

要检查 regulator 是否启动,可以使用下面的函数:

int regulator_is_enabled(regulator);

于需要根据操作模式调整电源的用户,内核提供了如下功能:

int regulator_set_voltage(regulator, min_uV, max_uV);

min_uV 和 max_uV 是以微伏为单位的最小和最大可接受电压。

如果在稳压器被禁用时调用该功能,则该功能将改变电压配置,以便在稳压器下次启用时物理设置电压
也就是说,消费者可以通过调用 regulator_get_voltage() 获得调节器配置的电压输出,无论调节器是否启用,它都会返回配置的输出电压:

我们在电压部分所讨论的问题在这里也适用。例如,USB驱动程序可能希望在供电时将限制设置为500 mA。

int regulator_set_current_limit(regulator, min_uA, max_uA);

min_uA 和 max_uA 是以微安为单位的最小和最大可接受电流限制。

同样,消费者可以通过调用 regulator_get_current_limit() 得到调节器配置的电流限制,无论调节器是否启用,调节器都会返回电流限制的值:

int regulator_get_current_limit(regulator);
使用Multi Regulator

消费者节点可以使用以下绑定引用一个或多个供应/调节器:
使用 name-supply : phandle to regualtor name 的方式进行引用

gpu:gpu@304000000 {
    mali-supply = <&S3A_LEVEL>
    vdd-supply = <&gpu_gdsc>

}

因为属性的名称中包含了 regulator 的name,已经足够有意义了,必须匹配 regulator_get() 函数的 id参数,以便驱动程序可以在请求调节器时轻松地引用它

这里的 regulator dts 注册方法有可能是这样的:

twl_reg1: regulator@0 {
  [...]
};

twl_reg2: regulator@1 {
  [...]
};

mmc: mmc@0x0 {
  [...]
  vmmc-supply = <&twl_reg1>;
  vmmcaux-supply = <&twl_reg2>;
};

参考博客

Linux regulator 框架理解和使用
代码位置:

driver/regulator/core.c
// dummy regulator 的参考实现
driver/regulator/dummy.c 
include/linux/regulator/consumer.h

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

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

相关文章

电子烟特效音语音方案选型-WTN6020-8S-E

随着科技的迅猛进步&#xff0c;电子烟行业亦在持续创新与突破&#xff0c;引领着全新的潮流。其中&#xff0c;电子烟产品所特有的吸烟声音特效播报功能&#xff0c;无疑成为了技术革新的璀璨亮点。这一设计巧妙地将吸烟的声效融入使用体验中&#xff0c;使得用户在吸电子烟时…

Javascript 斐波那契搜索-迭代与递归(Fibonacci Search)

给定一个大小为 n 的排序数组 arr[] 和要在其中搜索的元素 x。如果 x 存在于数组中&#xff0c;则返回 x 的索引&#xff0c;否则返回 -1。 例子&#xff1a; 输入&#xff1a; arr[] {2, 3, 4, 10, 40}, x 10输出&#xff1a; 3 元素 x 出现在索引 3 处。 输入&#xff1…

HarmonyOS开发实例:【app帐号管理】

应用帐号管理 介绍 本示例选择应用进行注册/登录&#xff0c;并设置帐号相关信息&#xff0c;简要说明应用帐号管理相关功能。效果图如下&#xff1a; 效果预览 使用说明参考鸿蒙文档&#xff1a;qr23.cn/AKFP8k点击或者转到。 1.首页面选择想要进入的应用&#xff0c;首次进…

【Redis】持久化

文章目录 一、RDB1.1、RDB的自动备份与手动备份1.1.1、自动备份1.1.2、手动备份 1.2、RDB优点1.3、RDB缺点1.4、RDB快照1.5、RDB优化配置项 二、AOF2.1、AOF工作流程2.2、AOF写回策略2.3、MP-AOF实现2.4、AOF优缺点2.5、AOF重写机制 三、RDBAOF混合持久化3.1、数据恢复顺序和加…

生产环境中秒杀接口并发量剧增与负载优化策略探讨

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 1. 实施限流措施 1.1 令牌桶算法&#xff1a; 1.2 漏…

如何申请阿里云服务器学生优惠,入口在这呢!

阿里云学生服务器免费申请&#xff0c;之前是云翼计划学生服务器9元/月&#xff0c;现在是高校计划&#xff0c;学生服务器可以免费申请&#xff0c;先完成学生认证即可免费领取一台云服务器ECS&#xff0c;配置为2核2G、1M带宽、40G系统盘&#xff0c;在云服务器ECS实例过期之…

什么是队头阻塞以及如何解决

前言 通常我们提到队头阻塞&#xff0c;指的可能是TCP协议中的队头阻塞&#xff0c;但是HTTP1.1中也有一个类似TCP队头阻塞的问题&#xff0c;下面各自介绍一下。 TCP队头阻塞 队头阻塞&#xff08;head-of-line blocking&#xff09;发生在一个TCP分节丢失&#xff0c;导致…

ip地址切换器安卓版,保护隐私,自由上网

在移动互联网时代&#xff0c;随着智能手机和平板电脑的普及&#xff0c;移动设备的网络连接变得愈发重要。为了满足用户在不同网络环境下的需求&#xff0c;IP地址切换器安卓版应运而生。本文将以虎观代理为例&#xff0c;为您详细解析IP地址切换器安卓版的功能、应用以及其所…

26、链表-环形链表II

思路&#xff1a; 这道题就是判断链表中是否有环&#xff0c;首先使用集合肯定可以快速地解决&#xff0c;比如通过一个set集合遍历&#xff0c;如果遍历过程中有节点在set中已经存在那么说明存在环。返回这个节点即可 第二种方式就是通过快慢指针方式寻找环。如何做呢&#xf…

震惊!借助Coze白嫖GPT4-128k解决方案

震惊!某大佬借助Coze白嫖GPT4-128k解决方案 前言 此文章介绍如何免费使用GPT-4高级模型并拓展API功能 最近的 Coze 在国内开放了&#xff0c;可以免费使用大模型。但是和国外的有点区别&#xff0c;国外版本使用的chatgpt4&#xff0c;国内版本使用的是语雀大模型。 Coze是一…

《前端防坑》- JS基础 - 你觉得typeof nullValue === null 么?

问题 JS原始类型有6种Undefined, Null, Number, String, Boolean, Symbol共6种。 在对原始类型使用typeof进行判断时, typeof stringValue string typeof numberValue number 如果一个变量(nullValue)的值为null&#xff0c;那么typeof nullValue "?" const u …

图书推荐:用ChatGPT获取在线被动收入的8个方法

Universe S. The ChatGPT Money Mastery. Unlocking Online Income..for Dummies 2023 想要彻底革新您的收入模式吗&#xff1f;《用ChatGPT获取在线被动收入的8个方法》一书是您不可错过的指南。 在这个数字化飞速发展的时代&#xff0c;人工智能成为了开启成功之门的钥匙。…

2024年广东省网络系统管理样题第1套网络搭建部分

2024年广东省职业院校技能大赛样题1 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加博主wx&#xff1a;liuliu5488233 网络系统管理赛项 模块A&#xff1a;网络…

操作系统(第四周 第二堂)

目录 回顾 进程运行 进程的创建 进程的工作 举例 进程的删除 举例1&#xff08;走到return 0结束&#xff09; 举例2&#xff08;利用exit&#xff08;1&#xff09;结束&#xff09; 进程通信 共享内存 生产者算法 消费者算法 消息传递 定义 算法实现 总结 回顾…

数据结构--链式队列

一.链式队列的设计思想: 首先一定要理解设计的初衷,就是队头队尾的位置要满足怎么快怎么设计.那么分析如下: 最终我们敲定了入队,出队的时间复杂度都为O(1)的一种设计,也就是第四种设计;当然,头节点的数据域不使用,所以我们设计链式队列的头节点的时候删除数据域即可,链式队列…

了解虚拟路由器冗余协议(VRRP)

虚拟路由器冗余协议&#xff08;VRRP&#xff09;是一种被广泛使用的网络协议&#xff0c;旨在增强网络的可靠性和可用性。对于网络管理员和工程师来说&#xff0c;了解VRRP是确保网络能够实现无缝故障转移和保持不间断连接的关键。本文将深入探讨VRRP的基础知识&#xff0c;包…

ZooKeeper分布式服务与Kafka消息队列+ELKF整合方案

前言 ZooKeeper 是一个分布式的、开放源码的分布式应用程序协调服务&#xff0c;提供配置维护、命名服务、分布式同步、组服务等功能&#xff1b; Kafka 是一个开源的分布式流处理平台&#xff0c;它被设计用来处理实时数据流&#xff0c;包括发布和订阅消息系统、日志收集以…

leetcode经典困难题-接雨水

. - 力扣&#xff08;LeetCode&#xff09; 42. 接雨水 困难 相关标签 相关企业 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,…

单链表详解(无哨兵位),实现增删改查

1.顺序表对比单链表的缺点 中间或头部插入时&#xff0c;需要移动数据再插入&#xff0c;如果数据庞大会导致效率降低每次增容就需要申请空间&#xff0c;而且需要拷贝数据&#xff0c;释放旧空间增容造成浪费&#xff0c;因为一般都是以2倍增容 2.链表的基础知识 链表也是线…

【JavaSE进阶】00-基础语法(13-14章) 01-面向对象 02-数组 03-常用类 04-异常处理

13 第十三章 方法覆盖和多态(Polymorphism)★★★★★ 13.1 章节目标与知识框架 13.1.1 章节目标 理解在什么情况下我们需要进行方法覆盖&#xff1f;掌握在满足什么条件的时候构成方法覆盖&#xff1f;什么是多态&#xff0c;代码怎么写&#xff1f;向上转型和向下转型都是…