当前位置: 首页 > news >正文

Linux clock子系统及驱动实例

文章目录

    • 基本概念
    • CLK子系统
    • 时钟API的使用
    • clock驱动实例
      • 1、时钟树
      • 2、设备树
      • 3、驱动实现
        • fixed_clk固定时钟实现
        • factor_clk分频时钟实现
        • gate_clk门控时钟实现

基本概念


晶振:晶源振荡器
PLL:Phase lock loop,锁相环。用于提升频率
OSC:oscillator的简写,振荡器

CLK子系统


Linux的时钟子系统由CCF(common clock framework)框架管理,CCF向上给用户提供了通用的时钟接口,向下给驱动开发者提供硬件操作的接口。各结构体关系如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ySJAJxZO-1676165714838)(pic/image-20230210213920508.png)]
CCF框架比较简单,只有这几个结构体。CCF框架分为了consumer、ccf和provider三部分。

consumer

​ 时钟的使用者,clock子系统向consumer的提供通用的时钟API接口,使其可以屏蔽底层硬件差异。提供给consumer操作的API如下:

struct clk *clk_get(struct device *dev, const char *id);
struct clk *devm_clk_get(struct device *dev, const char *id);
int clk_enable(struct clk *clk);//使能时钟,不会睡眠
void clk_disable(struct clk *clk);//使能时钟,不会睡眠
unsigned long clk_get_rate(struct clk *clk);
void clk_put(struct clk *clk);
long clk_round_rate(struct clk *clk, unsigned long rate);
int clk_set_rate(struct clk *clk, unsigned long rate);
int clk_set_parent(struct clk *clk, struct clk *parent);
struct clk *clk_get_parent(struct clk *clk);
int clk_prepare(struct clk *clk);
void clk_unprepare(struct clk *clk);
int clk_prepare_enable(struct clk *clk) //使能时钟,可能会睡眠
void clk_disable_unprepare(struct clk *clk) //禁止时钟,可能会睡眠
unsigned long clk_get_rate(struct clk *clk) //获取时钟频率

consumer在使用这些API时,必须先调用devm_clk_get()clk_get()获取一个struct clk *指针句柄,后续都通过传入该句柄来操作,struct clk相当于实例化一个时钟。

ccf

​ clock子系统的核心,用一个struct clk_core结构体表示,每个注册设备都对应一个struct clk_core

provider(时钟的提供者)

struct clk_hw:表示一个具体的硬件时钟。

struct clk_init_data:struct clk_hw结构体成员,用于表示该时钟下的初始化数据,如时钟名字name、操作函数ops等。

// include/linux/clk-provider.h
struct clk_hw{struct clk_core *core;struct clk *clk;const struct clk_init_data *init;
}struct clk_init_data{const char *name;					//时钟名字const struct clk_ops *ops;			//时钟硬件操作函数集合const char *const *parent_names;	//父时钟名字const struct clk_parent_data *parent_data;const struct clk_hw	**parent_hws;u8 num_parents;unsigned long flags;
}

struct clk_ops:时钟硬件操作的函数集合,定义了操作硬件的回调函数,consumer在调用clk_set_rate()等API时会调用到struct clk_ops具体指向的函数,这个需要芯片厂商开发clock驱动时去实现。

//include/linux/clk-provider.hstruct clk_ops {int		(*prepare)(struct clk_hw *hw);void		(*unprepare)(struct clk_hw *hw);int		(*is_prepared)(struct clk_hw *hw);void		(*unprepare_unused)(struct clk_hw *hw);int		(*enable)(struct clk_hw *hw);void		(*disable)(struct clk_hw *hw);int		(*is_enabled)(struct clk_hw *hw);void		(*disable_unused)(struct clk_hw *hw);int		(*save_context)(struct clk_hw *hw);void		(*restore_context)(struct clk_hw *hw);unsigned long	(*recalc_rate)(struct clk_hw *hw,unsigned long parent_rate);long		(*round_rate)(struct clk_hw *hw, unsigned long rate,unsigned long *parent_rate);int		(*determine_rate)(struct clk_hw *hw,struct clk_rate_request *req);int		(*set_parent)(struct clk_hw *hw, u8 index);u8		(*get_parent)(struct clk_hw *hw);int		(*set_rate)(struct clk_hw *hw, unsigned long rate,unsigned long parent_rate);int		(*set_rate_and_parent)(struct clk_hw *hw,unsigned long rate,unsigned long parent_rate, u8 index);unsigned long	(*recalc_accuracy)(struct clk_hw *hw,unsigned long parent_accuracy);int		(*get_phase)(struct clk_hw *hw);int		(*set_phase)(struct clk_hw *hw, int degrees);int		(*get_duty_cycle)(struct clk_hw *hw,struct clk_duty *duty);int		(*set_duty_cycle)(struct clk_hw *hw,struct clk_duty *duty);int		(*init)(struct clk_hw *hw);void		(*terminate)(struct clk_hw *hw);void		(*debug_init)(struct clk_hw *hw, struct dentry *dentry);
};

struct clk_ops中每个函数功能在include/linux/clk-provider.h都有具体的说明,在开发clock驱动时,这些函数并不需要全部实现。下面列举几个最常用,也是经常需要实现的函数。

函数说明
recalc_rate通过查询硬件,重新计算此时钟的速率。可选,但建议——如果未设置此操作,则时钟速率初始化为0。
round_rate给定目标速率作为输入,返回时钟实际支持的最接近速率。
set_rate更改此时钟的速率。请求的速率由第二个参数指定,该参数通常应该是调用.round_rate返回。第三个参数给出了父速率,这对大多数.set_rate实现有帮助。成功返回0,否则返回-EERROR
enable时钟enable
disable时钟disable

时钟API的使用


对于一般的驱动开发(非clock驱动),我们只需要在dts中配置时钟,然后在驱动调用通用的时钟API接口即可。
1、设备树中配置时钟

	mmc0:mmc0@0x12345678{compatible = "xx,xx-mmc0";......clocks = <&peri PERI_MCI0>;//指定mmc0的时钟来自PERI_MCI0,PERI_MCI0的父时钟是periclocks-names = "mmc0";	//时钟名,调用devm_clk_get获取时钟时,可以传入该名字......};

以mmc的设备节点为例,上述mmc0指定了时钟来自PERI_MCI0,PERI_MCI0的父时钟是peri,并将所指定的时钟给它命名为"mmc0"。

2、驱动中使用API接口

简单的使用:

/* 1、获取时钟 */
host->clk = devm_clk_get(&pdev->dev, NULL);	//或者devm_clk_get(&pdev->dev, "mmc0")if (IS_ERR(host->clk)) {dev_err(dev, "failed to find clock source\n");ret = PTR_ERR(host->clk);goto probe_out_free_dev;}/* 2、使能时钟 */
ret = clk_prepare_enable(host->clk);
if (ret) {dev_err(dev, "failed to enable clock source.\n");goto probe_out_free_dev;
}probe_out_free_dev:kfree(host);

在驱动中操作时钟,第一步需要获取struct clk指针句柄,后续都通过该指针进行操作,例如:
设置频率:

ret = clk_set_rate(host->clk, 300000);

获得频率:

ret = clk_get_rate(host->clk);

注意:devm_clk_get()的两个参数是二选一,可以都传入,也可以只传入一个参数。

像i2c、mmc等这些外设驱动,通常只需要使能门控即可,因为这些外设并不是时钟源,它们只有开关。如果直接调用clk_ser_rate函数设置频率,clk_set_rate会向上传递,即设置它的父时钟频率。例如在该例子中直接调用clk_set_rate函数,最终设置的是时钟源peri的频率。

clock驱动实例


clock驱动在时钟子系统中属于provider,provider是时钟的提供者,即具体的clock驱动。clock驱动在Linux刚启动的时候就要完成,比initcall都要早期,因此clock驱动是在内核中进行实现。在内核的drivers/clk目录下,可以看到各个芯片厂商对各自芯片clock驱动的实现:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mxXnZMfs-1676165714841)(pic/image-20230211094537328.png)]

下面以一个简单的时钟树,举例说明一个芯片的时钟驱动的大致实现过程:

1、时钟树

通常来说,一个芯片的时钟树是比较固定的,例如,以下时钟树:

在这里插入图片描述

时钟树的根节点一般是晶振时钟,上图根节点为24M晶振时钟。根节点下面是PLL,PLL用于提升频率。PPL0下又分频给PERI、DSP和ISP。PLL1分频给DDR和ENC。

对于PLL来说,PLL的频率可以通过寄存器设置,但通常是固定的,所以PLL属于固定时钟。

对PERI、DSP等模块来说,它们的频率来自于PLL的分频,因此这些模块的时钟属于分频时钟。

2、设备树

设备树中表示一个时钟源,应有如下属性,例如24Mosc:

clocks{osc24M:osc24M{compatible = "fixed-clock";#clock-cells = <0>;clock-output-name = "osc24M";clock-frequency = <24000000>;};
};
属性说明
compatible驱动匹配名字
#clock-cells提供输出时钟的路数。#clock-cells为0时,代表输出一路时钟
#clock-cells为1时,代表输出2路时钟。
#clock-output-names输出时钟的名字
#clock-frequency输出时钟的频率

3、驱动实现

clock驱动编写的基本步骤:

  1. 实现struct clk_ops相关成员函数
  2. 定义分配struct clk_onecell_data结构体,初始化相关数据
  3. 定义分配struct clk_init_data结构体,初始化相关数据
  4. 调用clk_register将时钟注册进框架
  5. 调用clk_register_clkdev注册时钟设备
  6. 调用of_clk_add_provider,将clk provider存放到of_clk_provider链表中管理
  7. 调用CLK_OF_DECLARE声明驱动

fixed_clk固定时钟实现

fixed_clk针对像PLL这种具有固定频率的时钟,对于PLL,我们只需要实现.recalc_rate函数
设备树:

#define PLL0_CLK 0clocks{osc24M:osc24M{compatible = "fixed-clock";#clock-cells = <0>;clock-output-names = "osc24M";clock-frequency = <24000000>;};pll0:pll0{compatible = "xx, choogle-fixed-clk";#clock-cells = <0>;clock-id = <PLL0_CLK>;clock-frequency = <1000000000>;clock-output-names = "pll0";clocks = <&osc24M>;};
};

驱动:

#include <linux/clk-provier.h>
#include <linux/clkdev.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/delay.h>#define CLOCK_BASE 0X12340000
#define CLOCK_SIZE	0X1000struct xx_fixed_clk{void __iomem *reg;//保存映射后寄存器基址unsigned long fixed_rate;//频率int id;//clock idstruct clk_hw*;
}static unsigned long xx_pll0_fixed_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{unsigned long recalc_rate;//硬件操作:查询寄存器,获得分频系数,计算频率然后返回return recalc_rate;
}static struct clk_ops xx_pll0_fixed_clk_ops = {.recalc_rate		= 		xx_pll0_fixed_clk_recalc_rate,
};struct clk_ops *xx_fixed_clk_ops[] = {&xx_pll0_fixed_clk_ops,
};struct clk * __init xx_register_fixed_clk(const char *name, const char *parent_name,void __iomem *res_reg, u32 fixed_rate, int id, const struct clk_ops *ops)
{struct xx_fixed_clk *fixed_clk;struct clk *clk;struct clk_init_data init = {};fixed_clk = kzalloc(sizeof(*fixed_clk), GFP_KERNEL);if (!fixed_clk)return ERR_PTR(-ENOMEM);//初始化struct clk_init_data数据init.name = name;init.flags = CLK_IS_BASIC;init.parent_names = parent_name ? &parent_name : NULL;init.num_parents = parent_name ? 1 : 0;fixed_clk->reg = res_reg;//保存映射后的基址fixed_clk->fixed_rate = fixed_rate;//保存频率fixed_clk->id = id;//保存clock idfixed_clk->hw.init = &init;//时钟注册clk = clk_register(NULL, &fixed_clk->hw);if (IS_ERR(clk))kfree(fixed_clk);return clk;
}static void __init of_xx_fixed_clk_init(struct device_node *np)
{struct clk_onecell_data *clk_data;const char *clk_name = np->name;const char *parent_name = of_clk_get_parent_name(np, 0);void __iomem *res_reg = ioremap(CLOCK_BASE, CLOCK_SIZE);//寄存器基址映射u32 rate = -1;int clock_id, index, number;clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);if (!clk_data )return;number = of_property_count_u32_elems(np, "clock-id");clk_data->clks = kcalloc(number, sizeof(struct clk*), GFP_KERNEL);if (!clk_data->clks)goto err_free_data;of_property_read_u32(np, "clock-frequency", &rate);/*** 操作寄存器:初始化PLL时钟频率* ......*/for (index=0; index<number; index++) {of_property_read_string_index(np, "clock-output-names", index, &clk_name);of_property_read_u32_index(np, "clock-id", index, &clock_id);clk_data->clks[index] = xx_register_fixed_clk(clk_name, parent_name, res_reg, rate, clock_id, ak_fixed_clk_ops[pll_id]);if (IS_ERR(clk_data->clks[index])) {pr_err("%s register fixed clk failed: clk_name:%s, index = %d\n",__func__, clk_name, index);WARN_ON(true);continue;}clk_register_clkdev(clk_data->clks[index], clk_name, NULL);//注册时钟设备}clk_data->clk_num = number;if (number == 1) {of_clk_add_provider(np, of_clk_src_simple_get, clk_data->clks[0]);} else {of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);}return;err_free_data:kfree(clk_data);}CLK_OF_DECLARE(xx_fixed_clk, "xx,xx-fixed-clk", of_xx_fixed_clk_init);

factor_clk分频时钟实现

peri的时钟来自于Pll的分频,对于这类时钟,需要实现.round_rate.set_rate.recalc_rate

设备树:

#define PLL0_CLK 0
#defeine PLL0_FACTOR_PERI 0clocks{osc24M:osc24M{//晶振时钟compatible = "fixed-clock";#clock-cells = <0>;clock-output-names = "osc24M";clock-frequency = <24000000>;};pll0:pll0{//pll倍频时钟compatible = "xx, xx-fixed-clk";#clock-cells = <0>;clock-id = <PLL0_CLK>;clock-frequency = <1000000000>;clock-output-names = "pll0";clocks = <&osc24M>;//pll的父时钟为24M晶振};factor_pll0_clk:factor_pll0_clk{//pll分频时钟compatible = "xx,xx-pll0-factor-clk";#clock-cells = <1>;clock-id = <PLL0_FACTOR_PERI>;clock-output-names = "pll0_peri";clocks = <&pll0 PLL0_CLK>;//PERI子系统的父时钟为pll0};
};

驱动:

static long xx_factor_pll0_clk_round_rate(struct  clk_hw *hw, unsigned long rate,unsigned long *parent_rate)
{unsigned long round_rate;//返回时钟实际支持的最接近速率return round_rate;
}
static int xx_factor_pll0_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
{int ret = 0;//操作寄存器,设置频率return ret;
}static unsigned long xx_factor_pll0_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{unsigned long recalc_rate;//查询寄存器,获得分频系数,计算频率然后返回return recalc_rate;}const struct clk_ops xx_factor_clk_ops = {.round_rate = xx_factor_pll0_clk_round_rate,//给定目标速率作为输入,返回时钟.set_rate = xx_factor_pll0_clk_set_rate,.recalc_rate = xx_factor_pll0_clk_recalc_rate,
}static void __init of_xx_factor_clk_init(struct device_node *np)
{//驱动入口//参考上述pll的注册,唯一不同的就是struct clk_ops的成员函数实现
}CLK_OF_DECLARE(xx_factor_clk, "xx,xx-factor-clk", of_xx_facotr_clk_init);

gate_clk门控时钟实现

门控就是开关,对于门控而言,我们只需要实现struct clk_ops的.enable和.disable
设备树:

#define PLL0_CLK 0
#defeine PLL0_FACTOR_PERI 0
#define PERI_MCI0 0mmc0:mmc0@0x12345678{compatible = "xx,xx-mmc0";......clocks = <&peri PERI_MCI0>;clocks-names = "mmc0";......};clocks{osc24M:osc24M{compatible = "fixed-clock";#clock-cells = <0>;clock-output-names = "osc24M";clock-frequency = <24000000>;};pll0:pll0{compatible = "xx, xx-fixed-clk";#clock-cells = <0>;clock-id = <PLL0_CLK>;clock-frequency = <1000000000>;clock-output-names = "pll0";clocks = <&osc24M>;};factor_pll0_clk:factor_pll0_clk{compatible = "xx,xx-pll0-factor-clk";#clock-cells = <1>;clock-id = <PLL0_FACTOR_PERI>;clock-output-names = "pll0_peri";clocks = <&pll0 PLL0_CLK>;};peri:peri{compatible = "xx,xx-gate-clk";#clock-cells = <1>;/*peri gate*/clock-id = <PERI_MCI0>;clock-output-names = "mci0_peri";clocks = <&factor_pll0_clk PLL0_FACTOR_PERI>;};
};

驱动:

static int xx_gate_clk_enable(struct clk_hw *hw)
{//寄存器操作,打开门控return 0;
}static int xx_gate_clk_disable(struct clk_hw *hw)
{//寄存器操作,门控关return 0;
}const struct clk_ops ak_gate_clk_ops = {.enable = xx_gate_clk_enable,.disable = xx_gate_clk_disable,
}static void __init of_xx_gate_clk_init(struct device_node *np)
{//参考上述fixed_clk的注册,几乎相同,只不过操作函数clk_ops的实现不一样
}CLK_OF_DECLARE(xx_gate_clk, "xx,xx-gate-clk", of_xx_gate_clk_init);

上述只是对clock驱动实现的简单举例,每个芯片厂商在clock驱动的实现上都有很大的差异。对于一般的驱动,只需要会简单的使用内核提供的时钟API接口即可。

相关文章:

Linux clock子系统及驱动实例

文章目录基本概念CLK子系统时钟API的使用clock驱动实例1、时钟树2、设备树3、驱动实现fixed_clk固定时钟实现factor_clk分频时钟实现gate_clk门控时钟实现基本概念 晶振&#xff1a;晶源振荡器 PLL&#xff1a;Phase lock loop&#xff0c;锁相环。用于提升频率 OSC&#xff1a…...

GIS数据格式坐标转换(地球坐标WGS84、GCJ-02、火星坐标、百度坐标BD-09、国家大地坐标系CGCS2000)

文章目录前言一、坐标系1.地球坐标 (WGS84)2.国测局坐标系(GCJ-02、火星坐标系)3.百度坐标(BD-09)4.国家大地2000坐标系(CGCS2000)二、百度坐标系(BD-09) 与火星坐标系(GCJ-02)的转换1.核心代码2.转换验证百度地图高德地图腾讯地图三、火星坐标系 (GCJ-02) 与百度坐标系 (BD-09…...

流媒体传输系列文章汇总

流媒体传输系列文章汇总 文章目录流媒体传输系列文章汇总引言流媒体交互协议详解视频封装协议详解流媒体环境搭建其他引言 从去年开始编写有关流媒体传输相关知识的文章&#xff0c;已发表文章22篇&#xff0c;阅读量也超过了10万&#xff0c;为了方便各位阅读&#xff0c;本文…...

“万字“ Java I/O流讲解

Java I/O流讲解 每博一文案 谁让你读了这么多书&#xff0c;又知道了双水村以外还有一个大世界&#xff0c;如果从小你就在这个天地里&#xff0c;日出而作&#xff0c;日落而息。 那你现在就会和众乡亲抱同一理想&#xff1a;经过几年的辛劳&#xff0c;像大哥一样娶个满意的…...

数据库(Spring)事务的四种隔离级别

文章目录Spring&#xff08;数据库&#xff09;事务隔离级别分为四种&#xff08;级别递减&#xff09;1、Serializable&#xff08;串行化&#xff09;2、REPEATABLE READ&#xff08;可重复读&#xff09;3、READ COMMITTED&#xff08;读以提交&#xff09;4、Read Uncommit…...

RabbitMQ详解(一):RabbitMQ相关概念

RabbitMQ是目前非常热门的一款消息中间件&#xff0c;不管是互联网大厂还是中小企业都在大量使用。作为一名合格的开发者&#xff0c;有必要对RabbitMQ有所了解&#xff0c;本系列是RabbitMQ快速入门文章&#xff0c;主要内容包括RabbitMQ是什么、RabbitMQ核心概念、五种消息模…...

​ICLR 2023 | GReTo:以同异配关系重新审视动态时空图聚合

©PaperWeekly 原创 作者 | 周正阳单位 | 中国科学技术大学论文简介动态时空图数据结构在多种不同的学科中均普遍存在&#xff0c;如交通流、空气质量观测、社交网络等&#xff0c;这些观测往往会随着时间而变化&#xff0c;进而引发节点间关联的动态时变特性。本文的主要…...

线程池分享总结

线程池介绍 可以复用线程池的每一个资源 控制资源的总量 为什么要使用线程池 问题一&#xff1a;反复创建线程开销大 问题二&#xff1a;过多的线程会占用太多内存 解决以上两个问题的思路 • 用少量的线程——避免内存占用过多 • 让这部分线程都保持工作&#xff0c;且可…...

AOSP Android11系统源码和内核源码

推荐阅读 商务合作 安全产品 安全服务 2023年招聘 安全培训服务 软件定制服务 Android系统定制服务 安全/软件开发的课程列表 1.下载repo工具 (1).创建bin&#xff0c;并加入到PATH中 mkdir ~/binPATH~/bin:$PATH (2).安装依赖库 sudo apt-get install bison g-mult…...

layui框架学习(6:基础菜单)

菜单是应用系统的必备元素&#xff0c;虽然网页中的导航也能作为菜单使用&#xff0c;但菜单和导航的样式和用途有所不同&#xff08;不同之处详见参考文献5&#xff09;。Layui中用不同的预设类定义菜单和导航的样式&#xff0c;同时二者依赖的模块也不一样。本文主要学习和记…...

第十三届蓝桥杯 C++ B组省赛 C 题——刷题统计(AC)

1.刷题统计 1.题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天 做 aaa 道题目, 周六和周日每天做 bbb 道题目。请你帮小明计算, 按照计划他将在 第几天实现做题数大于等于 nnn 题? 2.输入格式 输入一行包含三个整数 a,ba,ba,b 和 nnn. 3.输出…...

C++中的多态

【1】表现形式&#xff1a;同样的调用语句有多种不同的表现形态 【2】分类&#xff1a;静态联编和动态联编 静态联编有函数重载(运算符重载是特殊的函数重载),模板 【3】重点说下动态联编 【3.1】动态联编的实现需要以下步骤&#xff1a; 有继承关系、父类函数有virtual关…...

Swift如何保证线程安全

Swift可以通过以下几种方式来保证线程安全 使用互斥锁&#xff08;Mutex&#xff09;&#xff1a;使用互斥锁可以防止多个线程同时访问共享数据&#xff0c;保证线程安全。 使用OSAtomic操作&#xff1a;OSAtomic操作可以在多线程环境中安全地执行原子操作。 使用DispatchQue…...

整型提升+算术转换——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容是之前操作符那篇博客中没有讲完的内容&#xff0c;整型提升这个小知识点也非常重要&#xff0c;那现在&#xff0c;就让我们进入操作符的世界吧 隐式类型转换 算术转换 操作符的属性 隐式类型转换 表达式求值的顺序一部…...

Freemarker介绍

2. Freemarker介绍 FreeMarker 是一个用 Java 语言编写的模板引擎&#xff0c;它基于模板来生成文本输出。FreeMarker与 Web 容器无关&#xff0c;即在 Web 运行时&#xff0c;它并不知道 Servlet 或 HTTP。它不仅可以用作表现层的实现技术&#xff0c;而且还可以用于生成 XML…...

【软件测试开发】Junit5单元测试框架

目录1. 注解Test 注解BeforeEach BeforeAllAfterEach AfterAll2. 断言 assertassertequalsassertTrue assertFalseassertNull assertNotNull3. 用例执行顺序方法排序&#xff0c;通过 Order 注解来排序4. 测试套件 Suite5. 参数化单参数stringsints6. 参数化多参数CsvSourceCsv…...

【C语言技能树】程序环境和预处理

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

数据库的三大范式

1.为什么需要数据库设计 设计数据表的时候&#xff0c;要考虑很多的问题: 用户需要哪些数据&#xff0c;我们在数据表中要保存哪一些数据怎么保证数据表中的数据的正确性如何降低数据表的冗余度开发人员怎么才能更方便的使用数据库 如果数据库设计得不合理的话&#xff0c;可…...

【MT7628】开发环境搭建-Fedora12安装之后无法上网问题解决

1.按照如下图所示,打开Network Connections 2.点击Network Connections,弹出如下界面...

[Android Studio]Android 数据存储-文件存储学习笔记-结合保存QQ账户与密码存储到指定文件中的演练

&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Android Debug&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Topic 发布安卓学习过程中遇到问题解决过程&#xff0c;希望我的解决方案可以对小伙伴们有帮助。 &#x1f4cb;笔记目…...

【openGauss实战9】深度分析分区表

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…...

XSS跨站脚本攻击剖析与防御:初识XSS

目录 跨站脚本介绍 1. 什么是XSS跨站脚本 2. XSS跨站脚本实例 3. XSS漏洞的危害 XSS的分类 1. 反射型XSS 2. 持久性XSS XSS构造 1. 利用< >标记注射Html /Javascript 2. 利用HTML标签属性值执行XSS 3. 空格回车Tab 4. 对标签属性值转码 5. 产生自己的事件…...

Python 高级编程之网络编程 Socket(六)

文章目录一、概述二、Python socket 模块1&#xff09;Socket 类型1、创建 TCP Socket2、创建 UDP Socket2&#xff09;Socket 函数1、服务端socket函数2、客户端socket函数3、公共socket函数三、单工&#xff0c;半双工以及全双工通信方式的区别四、单工&#xff0c;半双工以及…...

centos学习记录

遇到的问题及其解决办法 centos7安装图形化界面 yum groupinstall ‘X Window System’ yum groupinstall -y ‘GNOME Desktop’ 安装完成后输入init 5进入图形化界面 centos7安装vmware-tools 第一步卸载open-vm-tools 输入命令 yum remove open-vm-tools 输入命令 reboot 在…...

为什么说网络安全是风口行业?

前言 “没有网络安全就没有国家安全”。当前&#xff0c;网络安全已被提升到国家战略的高度&#xff0c;成为影响国家安全、社会稳定至关重要的因素之一。 网络安全行业特点 1、就业薪资非常高&#xff0c;涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万&…...

12-PHP使用过的函数 111-120

111、rowCount if ($stmt->execute($data)) {//true//读:select//写:insert,update,delete,成功后会返回表中受影响的记录数量//!rowCount() 返回受影响的记录数量if ($stmt->rowCount() > 0) {echo 新增成功,id . $db->lastInsertId() . <hr>;} else {//…...

【JavaWeb项目】简单搭建一个前端的博客系统

博客系统项目 本项目主要分成四个页面: 博客列表页博客详情页登录页面博客编辑页 该系统公共的CSS样式 common.css /* 放置一些各个页面都会用到的公共样式 */* {margin: 0;padding: 0;box-sizing: 0; }/* 给整个页面加上背景 */ html, body{height: 100%; }body {backgrou…...

iPerf3 -M参数详解,场景分析

本文目录iPerf3 -M参数说明几个典型测试场景中应该如何设定合适的-M参数值理想局域网模型&#xff08;无丢包&#xff0c;无抖动&#xff09;高丢包&#xff0c;无抖动模型高丢包&#xff0c;高抖动模型&#xff08;网络质量比较差&#xff0c;IP转发路径变化频繁&#xff09;总…...

java的基本语法以及注意事项

Java 基础语法一个 Java 程序可以认为是一系列对象的集合&#xff0c;而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。对象&#xff1a;对象是类的一个实例&#xff0c;有状态和行为。例如&#xff0c;一条狗是一个对象&#xff0c;它…...

matlab搭建IAE,ISE,ITAE性能指标

目录前言准备IAEISEITAE前言 最近在使用matlab搭建控制系统性能评价指标模型&#xff0c;记录一下 准备 MATLAB R2020 IAE IAE函数表达式如下所示&#xff1a; IAE函数模型如下所示&#xff1a; ISE ISE函数表达式如下所示&#xff1a; ISE函数模型如下所示&#xff…...

自建网站怎么做推广/武汉搜索引擎排名优化

SQLserver查看哪些表是非空表 --这个根据存储区来判断select B.name from sys.partitions A inner join sys.objects Bon A.object_idB.object_id where B.typeU and A.rows>0--这个根据索引表来判断select B.name from sysindexes A inner join sys.objects Bon A.idB…...

在境外做色情网站/宁波网站关键词排名推广

可以参考此篇博文. http://www.cnblogs.com/linjiqin/archive/2013/03/24/2979736.html 不过我按照其步骤手动安装Linux的rar文件执行make命令并没有成功安装.... 在线通过yum 安装有时候会出现无法解析一些网站的情况,造成安装失败. 这个有时候需要分时间(我在线安装的时间是…...

商丘专业做网站公司/网络营销推广公司

Eclipse January是Java中的一组常见数据结构&#xff0c;包括一个用于处理数字数据的强大库。 随着数据量和复杂性的急剧增加&#xff08;即所谓的“大数据”&#xff09;&#xff0c;Eclipse January提供了一个数字库&#xff0c;可以简化多维数组形式的数据的处理和操作。 库…...

精彩的网格布局网站/百度推广北京总部电话

1.定义程序中频繁使用的常量#include <iostream> using namespace std; const double PI3.1415926; int main() { cout<<"圆的面积是:"<<PI*3*3<<endl; cout<<"周长是:"<<2*PI*3<<endl; return 0; }和define定义…...

网站编辑怎么做/免费网站建设模板

【IT168 资讯】华为的三款模块化机架服务器产品已经将旧版Xeons更新到Skylake&#xff0c;从而提供更新的网络和存储选项。今年早些时候&#xff0c;华为开始对其服务器产品进行Skylake更新&#xff0c;从其E系列刀片服务器开始&#xff0c;即CH121和CH242 V5。现在已经转移到模…...

做网站服务器租一年多少钱/石家庄seo公司

背景说明 项目中使用jQuery DataTables插件来实现分页表格&#xff0c;但是默认的分页样式不能输入页码进行跳转&#xff0c;在页数非常多的时候使用很不方便&#xff0c;最主要的还是没有达到产品部门的设计要求&#xff0c;所以我需要寻找相应的解决方案。原始效果图目标效果…...