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

嵌入式驱动开发详解3(pinctrl和gpio子系统)

文章目录

  • 前言
  • pinctrl子系统
    • pin引脚配置
    • pinctrl驱动详解
  • gpio子系统
    • gpio属性配置
    • gpio子系统驱动
    • gpio子系统API函数
    • 与gpio子系统相关的of函数
  • pinctrl和gpio子系统的使用
    • 设备树配置
    • 驱动层部分
    • 用户层部分

前言

如果不用pinctrl和gpio子系统的话,我们开发驱动时需要先在设备树或者驱动文件中对pin进行配置成相应的功能引脚,然后如果是gpio功能的话就需要进行gpio初始化,如果是其他外设的话就需要进行其他外设的初始化,因为经常将引脚配置为gpio模式,因此linux内核针对pin的配置特意推出了pinctrl子系统,针对gpio的配置推出了gpio子系统,对于一些其他的外设模式有其他特定的子系统,这里不做讲解。

pinctrl子系统

大多数 SOC 的 pin 都是支持复用的,比如 I.MX6ULL 的 GPIO1_IO03 既可以作为普通的 GPIO 使用,也可以作为 I2C1 的 SDA 等等。此外我们还需要配置 pin 的电气特性,比如上/下 拉、速度、驱动能力等等。传统的配置 pin 的方式就是直接操作相应的寄存器,但是这种配置 方式比较繁琐、而且容易出问题(比如 pin 功能冲突)。pinctrl 子系统就是为了解决这个问题而引 入的,pinctrl 子系统主要工作内容如下:

  • ①、获取设备树中 pin 信息。
  • ②、根据获取到的 pin 信息来设置 pin 的复用功能
  • ③、根据获取到的 pin 信息来设置 pin 的电气特性,比如上/下拉、速度、驱动能力等。

对于我们使用者来讲,只需要在设备树里面设置好某个 pin 的相关属性即可,其他的初始 化工作均由 pinctrl 子系统来完成,pinctrl 子系统源码目录为 drivers/pinctrl。

pin引脚配置

要使用 pinctrl 子系统,我们需要在设备树里面设置 PIN 的配置信息,毕竟 pinctrl 子系统要 根据你提供的信息来配置 PIN 功能,一般会在设备树里面创建一个节点来描述 PIN 的配置信息。
在dtsi 文件,有一个叫做 iomuxc 的节点就是配置对应的pin引脚信息,但是这个文件里面只设置了iomuxc寄存器的起始地址,剩下的具体配置是在具体的设备树dts文件中追加的,结合起来之后如下所示:

iomuxc: iomuxc@020e0000 
{compatible = "fsl,imx6ul-iomuxc";reg = <0x020e0000 0x4000>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_hog_1>;imx6ul-evk {pinctrl_hog_1: hoggrp-1 {fsl,pins = < MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x13058 >; ......};}; 
};

对于一个 PIN 的配置主要包括两方面, 一个是设置这个 PIN 的复用功能,另一个就是设置这个 PIN 的电气特性。所以在每个子节点中类似UART1_RTS_B的定义就对应的设置好了 UART1_RTS_B 的复用功能和 UART1_RTS_B 的电气特性。例如,我们可以在pinfunc.h 这个头文件找到UART1_RTS_B的定义如下:

#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031C 0x0000 0x5 0x0

0x0090 0x031C 0x0000 0x5 0x0,这 5 个值的含义如下所示:

<mux_reg conf_reg input_reg mux_mode input_val>

三个reg就是对应前面所提到的iomuxc的基地址的偏移值,前三个刚好对应上复用功能寄存器,电气属性寄存器和输入寄存器,第四个和第五个就是复用功能寄存器的值和输入寄存器的值,而电气属性寄存器的值放在了宏定义MX6UL_PAD_UART1_RTS_B__GPIO1_IO19的后面0x17059 。

pinctrl驱动详解

关于pinctrl驱动的具体实现我这里不做过多赘述,我们只需要掌握怎么把设备树的pin给配置好就行,配置好之后pinctrl驱动就会自动的把引脚配置成想要的状态。由于内核都封装好了,所以只需大概将一下实现流程。
在这里插入图片描述如上图所示,pinctrl子系统的实现也是通过platform实现的,当pinctrl驱动与对应的compatible(在刚刚提到的pin配置的节点信息的最前面设置好了)匹配上之后就会执行probe函数,probe函数就会根据节点下面的pin配置给对应的寄存器写入对应的值。

gpio子系统

如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话,那么接下来就要用到 gpio 子系 统了。gpio 子系统顾名思义,就是用于初始化 GPIO 并且提供相应的 API 函数,比如设置 GPIO 为输入输出,读取 GPIO 的值等。gpio 子系统的主要目的就是方便驱动开发者使用 gpio,驱动 开发者在设备树中添加 gpio 相关信息,然后就可以在驱动程序中使用 gpio 子系统提供的 API 函数来操作 GPIO,Linux 内核向驱动开发者屏蔽掉了 GPIO 的设置过程,极大的方便了驱动开 发者使用 GPIO。

gpio属性配置

/* 根节点下linux内核中的gpio1属性配置*/
/ {
…………soc {…………gpmi: gpmi-nand@01806000{…………aips1: aips-bus@02000000 {…………gpio1: gpio@0209c000 {compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";reg = <0x0209c000 0x4000>;interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;gpio-controller;#gpio-cells = <2>;interrupt-controller;#interrupt-cells = <2>;};};};};
};/* 根节点下手动添加某个设备节点*/
/ {
…………beep{#address-cells = <1>;#size-cells = <1>;compatible = "hbb-beep";pinctrl-names = "default";pinctrl-0 = <&pinctrl_beep>;beep-gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;status = "okay";};
};

如上所示, GPIO子系统配置时是根据根节点下linux内核中的gpio1属性配置的,但是还需要gpio编号才能知道去配置哪个gpio,因此我们需要自己手动在根节点下手动添加某个设备节点(这里的节点跟上一个帖子的节点不同,这里仅仅只是设备树的节点,可以通过cd /proc/device-tree命令查看设备树节点是否添加成功) ,通过在自己写的驱动从设备树中读取出设备编号,然后将此编号通过gpio子系统的API函数输入来操作配置GPIO寄存器即可。在上面自己手动添加的节点中:

pinctrl-0 = <&pinctrl_beep>; //这个是前面提到的pinctrl属性配置
beep-gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>; //这个就是gpio的编号设置,因此前面的beep-gpio跟驱动有关联

很多初次接触设备树的驱动开发人员很容易因为这个小问题栽了大跟头!因为我们所使用 的设备树基本都是在半导体厂商提供的设备树文件基础上修改而来的,而半导体厂商提供的设 备树是根据自己官方开发板编写的,很多 PIN 的配置和我们所使用的开发板不一样。比如 A 这 个引脚在官方开发板接的是 I2C 的 SDA,而我们所使用的硬件可能将 A 这个引脚接到了其他 的外设,比如 LED 灯上,接不同的外设,A 这个引脚的配置就不同。一个引脚一次只能实现一 个功能,如果 A 引脚在设备树中配置为了 I2C 的 SDA 信号,那么 A 引脚就不能再配置为 GPIO, 否则的话驱动程序在申请 GPIO 的时候就会失败。
检查 PIN 有没有被其他外设使用包括两个方 面:
①、检查 pinctrl 设置。
②、如果这个 PIN 配置为 GPIO 的话,检查这个 GPIO 有没有被别的外设使用。

gpio子系统驱动

在drivers/gpio/目录下的.c文件就是不同芯片厂商的gpio驱动文件,跟pinctrl子系统一样,通过linux驱动的分层与分离、平台设备驱动相关内容封装好了,我们做驱动开发只要能掌握GPIO子系统的API函数的使用就行,后期如果有想法深入研究内核的开发,可以仔细研究一下具体是怎么实现的。

gpio子系统API函数

对于驱动开发人员,设置好设备树以后就可以使用 gpio 子系统提供的 API 函数来操作指定 的 GPIO,gpio 子系统向驱动开发人员屏蔽了具体的读写寄存器过程。这就是驱动分层与分离的好处,gpio 子系统提供的常用的 API 函数有下面几个:
gpio_request :用于申请一个 GPIO 管脚,在使用一个 GPIO 之前一定要使用 gpio_request 进行申请,函数原型如下:

int gpio_request(unsigned gpio, const char *label)

gpio_free:如果不使用某个 GPIO 了,那么就可以调用 gpio_free 函数进行释放。函数原型如下:

void gpio_free(unsigned gpio)

gpio_direction_input:此函数用于设置某个 GPIO 为输入,函数原型如下所示:

int gpio_direction_input(unsigned gpio)

gpio_direction_output:此函数用于设置某个 GPIO 为输出,并且设置默认输出值,函数原型如下:

int gpio_direction_output(unsigned gpio, int value)

gpio_get_value:此函数用于获取某个 GPIO 的值(0 或 1),此函数是个宏,定义所示:

#define gpio_get_value __gpio_get_value 
int __gpio_get_value(unsigned gpio)

gpio_set_value:此函数用于设置某个 GPIO 的值,此函数是个宏,定义如下

#define gpio_set_value __gpio_set_value 
void __gpio_set_value(unsigned gpio, int value)

以上只说明了有哪几个函数,具体函数怎么用可自行百度更加详细。

与gpio子系统相关的of函数

首先展示五个跟设备树的节点获取相关的五个OF函数:
of_find_node_by_name:过节点名字查找指定的节点;
of_find_node_by_type:通过 device_type 属性查找指定的节点
of_find_compatible_node:根据 device_type 和 compatible 这两个属性查找指定的节点
of_find_matching_node_and_match:通过 of_device_id 匹配表来查找指定的节点
of_find_node_by_path:通过路径来查找指定的节点,这个是我们经常用的方法。

前面的GPIO子系统的函数可以配置gpio的寄存器,但是在驱动程序中需要先读取 gpio 属性内容,因此Linux 内核提供了几个与 GPIO 有关 的 OF 函数,常用的几个 OF 函数如下所示:
of_get_named_gpio:此函数获取 GPIO 编号,因为 Linux 内核中关于 GPIO 的 API 函数都要使用 GPIO 编号, 此函数会将设备树中类似<&gpio5 7 GPIO_ACTIVE_LOW>的属性信息转换为对应的 GPIO 编 号,此函数在驱动中使用很频繁! 函数原型如下:

int of_get_named_gpio(struct device_node *np, const char *propname, int index)

np:设备节点。
propname:包含要获取 GPIO 信息的属性名。
index:GPIO 索引,因为一个属性里面可能包含多个 GPIO,此参数指定要获取哪个 GPIO 的编号,如果只有一个 GPIO 信息的话此参数为 0。
返回值:正值,获取到的 GPIO 编号;负值,失败。

还有一些其他的跟gpio相关的of函数,但是不怎么常用,比如of_gpio_named_count和of_gpio_count,可以获取pio配置的数量。

pinctrl和gpio子系统的使用

下面将展示一个具体的例子来说明pinctrl子系统和gpio子系统具体怎么用的。

设备树配置

设备树的配置可以看前面pinctrl的配置和在设备树根文件下对gpio信息的配置

驱动层部分

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>  //copy
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h> 
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define BEEP_CNT 1
#define BEEP_NAME "beep"
#define BEEP_ON 1
#define BEEP_OFF 0struct beep_dev{dev_t devid; int major;int minor;struct cdev cdev;struct class *class;struct device *device;struct device_node *nd;int beep_gpio;
};struct beep_dev beep;static int beep_open(struct inode *inode, struct file *file)
{file->private_data = &beep;return 0;
}static ssize_t beep_write(struct file *file, const char __user *buf,size_t count, loff_t *off)
{unsigned char status;int ret;struct beep_dev *dev = file->private_data;ret = copy_from_user(&status,buf,count);if(ret < 0){printk("kernel write failed!!!");return -1;}printk("device write%d\r\n",status);if(status == BEEP_ON){gpio_set_value(dev->beep_gpio, 0);}else if(status == BEEP_OFF){gpio_set_value(dev->beep_gpio, 1);}return 0;
}int beep_release(struct inode *inode, struct file *file)
{return 0;}static const struct file_operations beep_fops = {.owner	= THIS_MODULE,.open	= beep_open,.write	= beep_write,.release = beep_release,
};static int __init gpioled_init(void)
{int ret;beep.nd = of_find_node_by_path("/beep");if(beep.nd == NULL){printk("beep node cant not find!!\r\n");ret = -1;goto fail_node;}else{printk("beep node found!!\r\n");}beep.beep_gpio = of_get_named_gpio(beep.nd,"beep-gpio",0);if(beep.beep_gpio < 0){printk("cant not get beep-gpio\r\n");ret = -1;goto fail_node;}printk("beep-gpio-num=%d\r\n",beep.beep_gpio);ret = gpio_direction_output(beep.beep_gpio,1);if(ret < 0){printk("can`t set gpio!!!\r\n");}if(beep.major){beep.devid = MKDEV(beep.major,beep.minor);ret = register_chrdev_region(beep.devid, BEEP_CNT, BEEP_NAME);}else{ret = alloc_chrdev_region(&beep.devid,0,BEEP_CNT,BEEP_NAME);beep.major = MAJOR(beep.devid);beep.minor = MINOR(beep.devid);printk("alloc_chrdev_region major=%d minor=%d\r\n",beep.major, beep.minor);}if (ret < 0) {printk("Could not register\r\n");goto fail_devid;}beep.cdev.owner = THIS_MODULE;cdev_init(&beep.cdev, &beep_fops);ret = cdev_add(&beep.cdev,beep.devid,BEEP_CNT);if(ret < 0){printk("Could not cdev\r\n");goto fail_cdev;}beep.class = class_create(THIS_MODULE,BEEP_NAME);if(IS_ERR(beep.class)){ret = PTR_ERR(beep.class);goto fail_class;}beep.device = device_create(beep.class,NULL,beep.devid,NULL,BEEP_NAME);if(IS_ERR(beep.device)){ret = PTR_ERR(beep.device);goto fail_device;}return 0;
fail_device:class_destroy(beep.class);
fail_class:cdev_del(&beep.cdev);
fail_cdev:unregister_chrdev_region(beep.devid,BEEP_CNT);
fail_devid:
fail_node:return ret;
}static void __exit gpioled_exit(void)
{gpio_set_value(beep.beep_gpio,1);printk("beep_exit\r\n");cdev_del(&beep.cdev);unregister_chrdev_region(beep.devid,BEEP_CNT);device_destroy(beep.class,beep.devid);class_destroy(beep.class);
}module_init(gpioled_init);
module_exit(gpioled_exit);
MODULE_LICENSE("GPL");	
MODULE_AUTHOR("hbb");

用户层部分

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "string.h"int main(int argc,char *argv[])
{int fd,ret;char *filename;unsigned char databuf;if(argc != 3){printf("Error Usage!!!\r\n");return -1;}filename = argv[1];fd = open(filename ,O_RDWR);if(fd < 0){printf("file %s open failed!\r\n",filename);return -1;}databuf = atoi(argv[2]);ret = write(fd,&databuf,sizeof(databuf));if(ret < 0){printf("BEEP control failed\r\n");close(fd);return -1;}ret = close(fd);if(ret < 0){printf("file %s close failed! \r\n",filename);return -1;}return 0;
}

到这里对pinctrl和gpio子系统的大致说明就结束了,后面有新的相关的重要的内容会继续进行更新。
对代码有兴趣的同学可以查看链接https://github.com/NUAATRY/imx6ull_dev

相关文章:

嵌入式驱动开发详解3(pinctrl和gpio子系统)

文章目录 前言pinctrl子系统pin引脚配置pinctrl驱动详解 gpio子系统gpio属性配置gpio子系统驱动gpio子系统API函数与gpio子系统相关的of函数 pinctrl和gpio子系统的使用设备树配置驱动层部分用户层部分 前言 如果不用pinctrl和gpio子系统的话&#xff0c;我们开发驱动时需要先…...

使用 OpenCV 进行视频中的行人检测

在计算机视觉领域&#xff0c;行人检测是一个重要的研究方向&#xff0c;它在视频监控、自动驾驶、人机交互等领域都有着广泛的应用。本文将介绍如何使用 OpenCV 库来实现视频中的行人检测。 环境准备 首先&#xff0c;我们需要安装 OpenCV 库。可以通过以下命令来安装&#…...

py文件转pyd文件的那些坑

当编译py脚本文件发给客户使用时&#xff0c;为了保密源代码防止反编译&#xff0c;可以将py文件转换为pyd文件&#xff0c;然后使用pyinstaller工具转换为exe应用程序&#xff0c;但有时测试发现&#xff0c;py文件可以正常运行&#xff0c;转换为pyd文件后却有各种错误&#…...

go interface(接口)使用

在 Go 语言中&#xff0c;接口&#xff08;interface&#xff09;是一种抽象类型&#xff0c;它定义了一组方法&#xff0c;但是不实现这些方法。接口指定了一个对象的行为&#xff0c;而不关心对象的具体实现。接口使得代码更加灵活和可扩展。 定义接口 接口使用 type 关键字…...

前端---HTML(一)

HTML_网络的三大基石和html普通文本标签 1.我们要访问网络&#xff0c;需不需要知道&#xff0c;网络上的东西在哪&#xff1f; 为什么我们写&#xff0c;www.baidu.com就能找到百度了呢&#xff1f; 我一拼ping www.baidu.com 就拼到了ip地址&#xff1a; [119.75.218.70]…...

unsloth vlm模型Qwen2-VL、Llama 3.2 Vision微调案例

T4卡15G显卡训练 参考: https://github.com/unslothai/unsloth 按自己显卡cuda版本安装 免费colab微调代码: Qwen2-VL: https://colab.research.google.com/drive/1whHb54GNZMrNxIsi2wm2EY_-Pvo2QyKh?usp=sharing from unsloth import FastVisionModel # NEW instead …...

云网络基础- TCP/IP 协议

文章目录 典型服务模式TCP/IP 协议设置和查看IPIP地址的分类:IP地址组成: 网络位主机位组成克隆:产生一台新的虚拟机win2008 典型服务模式 • C/S,Client/Server架构 – 由服务器提供资源或某种功能 – 客户机使用资源或功能 TCP/IP 协议 • TCP/IP是最广泛支持的通信协议集合…...

【数据分享】2001-2023年我国30米分辨率冬小麦种植分布栅格数据(免费获取)

小麦、玉米、水稻等各类农作物的种植分布数据在农业、环境、国土等很多专业都经常用到&#xff01; 本次给大家分享的是我国2001-2023年逐年的30米分辨率冬小麦种植分布栅格数据&#xff01;数据格式为TIFF格式&#xff0c;数据坐标为GCS_WGS_1984。该数据包括我国11个省份的冬…...

前端预览pdf文件流

需求 后端接口返回pdf文件流&#xff0c;实现新窗口预览pdf。 解决方案 把后端返回的pdf文件流转为blob路径&#xff0c;利用浏览器直接预览。 具体实现步骤 1、引入axios import axios from axios;2、创建预览方法&#xff08;具体使用时将axios的请求路径替换为你的后端…...

【Leetcode 每日一题】146. LRU 缓存(c++)

146. LRU 缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#x…...

Neural Magic 发布 LLM Compressor:提升大模型推理效率的新工具

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

QT简易项目 数据库可视化界面 数据库编程SQLITE QT5.12.3环境 C++实现

案例需求&#xff1a; 完成数据库插入&#xff0c;删除&#xff0c;修改&#xff0c;查看操作。 分为 插入&#xff0c;删除&#xff0c;修改&#xff0c;查看&#xff0c;查询 几个模块。 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget…...

为什么DDoS防御很贵?

分布式拒绝服务攻击&#xff08;DDoS攻击&#xff09;是一种常见的网络安全威胁&#xff0c;通过大量恶意流量使目标服务器无法提供正常服务。DDoS防御是一项复杂且昂贵的服务&#xff0c;本文将详细探讨为什么DDoS防御如此昂贵&#xff0c;并提供一些实用的代码示例和解决方案…...

Spring Boot3远程调用工具RestClient

Spring Boot3.2之后web模块提供了一个新的远程调用工具RestClient&#xff0c;它的使用比RestTemplate方便&#xff0c;开箱即用&#xff0c;不需要单独注入到容器之中&#xff0c;友好的rest风格调用。下面简单的介绍一下该工具的使用。 一、写几个rest风格测试接口 RestCont…...

C51相关实验

C51相关实验 LED //功能&#xff1a;1.让开发板的LED全亮&#xff0c;2,点亮某一个LED,3.让LED3以5Hz的频率闪动#include "reg52.h"#define LED P2 sbit led1 LED^1;void main(void) {LED 0xff;//LED全灭led1 0;while(1)//保持应用程序不退出{} }LED 输出端是高…...

云服务器部署springboot项目、云服务器配置JDK、Tomcat

目录 环境准备&#xff1a;JDK、Tomcat 将两个文件上传刀usr/java目录下并解压&#xff1a; 改java相关文件里的参数 执行以下命令&#xff0c;打开 profile 文件 执行以下命令&#xff0c;读取环境变量&#xff1a; 查看JDK是否安装成功&#xff1a; 改Tomcat参数 项目…...

STM32 USART串口发送

单片机学习&#xff01; 目录 前言 一、串口发送配置步骤 二、详细步骤 2.1 RCC开启USART和GPIO时钟 2.2 GPIO初始化 2.3 配置USART 2.4 开启USART 2.5 初始化总代码 三、发送数据函数设计 3.1 发送一个字节数据函数 3.2 发送一个数组函数 3.3 发送字符串函数 3.4…...

二叉树的深度搜索专题一>计算布尔二叉树的值

题目&#xff1a; 题目解析&#xff1a; 算法解析&#xff1a; 代码&#xff1a; public boolean evaluateTree(TreeNode root) {if(root.left null && root.right null) return root.val 1 ? true : false;boolean leftTree evaluateTree(root.left);boolean…...

Web day01 html css

目录 1.html: 常用标签&#xff1a; 1.video img p br b u i s &#xff1a; 2.布局标签&#xff1a;div span 3.表单标签&#xff1a; 4.表单标签项&#xff1a; 5.表格标签: 2.css: 1.使用样式: 2.选择器&#xff1a; 3.样式&#xff1a; 1.color&#xff1a; 2. …...

PHP 超级全局变量

超级全局变量是指在php任意脚本下都可以使用 PHP 超级全局变量列表: $GLOBALS&#xff1a;是PHP的一个超级全局变量组&#xff0c;在一个PHP脚本的全部作用域中都可以访问。 $_SERVER&#xff1a;$_SERVER 是一个PHP内置的超级全局变量,它是一个包含了诸如头信息(header)、路…...

题目:素数列

思路&#xff1a; 注意审题&#xff0c;题目中的等差素数列指公差相同且每一个元素都是素数的数列&#xff0c;并不是说是所有素数中一段连续且插值相同的数列&#xff0c;它可以是离散的。 因此&#xff0c;只需要暴力的遍历每一个素数&#xff0c;并找以其开头的所有可能等差…...

机器学习系列-决策树

文章目录 1. 决策树原理决策树的构建流程 2. 案例步骤 1&#xff1a;计算当前节点的熵步骤 2&#xff1a;对每个特征计算分裂后的熵(1) 按“天气”分裂数据集(2) 计算分裂后的加权熵 步骤 3&#xff1a;计算分裂依据信息增益信息增益率GINI系数&#xff08;二叉树&#xff09; …...

H3C OSPF 多区域实验

目录 前言 实验拓扑 实验需求 实验解析 路由器配置 测试 前言 此篇文章为 OSPF多区域试验&#xff0c;建议先食用OSPF单区域实验&#xff0c;理解实验原理 学习基本配置&#xff0c;再来使用此篇&#xff0c;效果更佳&#xff01;&#xff08;当然如果你已经了解原理与基…...

【Python】 深入理解Python的单元测试:用unittest和pytest进行测试驱动开发

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 单元测试是现代软件开发中的重要组成部分,通过验证代码的功能性、准确性和稳定性,提升代码质量和开发效率。本文章深入介绍Python中两种主流单元测试框架:unittest和pytest,并结合测试驱动开发(TDD)…...

微信小程序中使用iconfont的详细教程

我们知道微信小程序对包体积有很严格的要求&#xff0c;最大不超过2M&#xff0c;而图片资源对包体检有至关重要的影响&#xff0c;所以使用自定义的图标字体来代替大量图标图片也是提高小程序性能的重要手段&#xff0c;总的来说在微信小程序中使用 IconFont&#xff08;图标字…...

【小白学机器学习33】 大数定律python的 pandas.Dataframe 和 pandas.Series基础内容

目录 0 总结 0.1pd.Dataframe有一个比较麻烦琐碎的地方&#xff0c;就是引号 和括号 0.2 pd.Dataframe关于括号的原则 0.3 分清楚几个数据类型和对应的方法的范围 0.4 几个数据结构的构造关系 list → np.array(list) → pd.Series(np.array)/pd.Dataframe 1 python 里…...

hue 4.11容器化部署,已结合Hive与Hadoop

配合《Hue 部署过程中的报错处理》食用更佳 官方配置说明页面&#xff1a; https://docs.gethue.com/administrator/configuration/connectors/ 官方配置hue.ini页面 https://github.com/cloudera/hue/blob/master/desktop/conf.dist/hue.ini docker部署 注意&#xff1a; …...

“软件定义汽车”时代 | 产线海量数据刷写解决方案

一 背景 从起初汽车概念问世时期的“机械定义汽车”&#xff0c;到电力出现后的“电器定义汽车”&#xff0c;再到电子科技迅猛发展后的“电子定义汽车”&#xff0c;再到如今的“软件定义汽车”&#xff0c;可以看出&#xff0c;软件在车辆中扮演着越来越重要的角色。与此同时…...

DDoS对策是什么?详细解读DDoS攻击难以防御的原因与解决方案

近年来&#xff0c;DDoS&#xff08;分布式拒绝服务&#xff09;攻击的规模和频率不断增加。根据数据显示&#xff0c;2023年已观测到的最大攻击流量达到700Gbps&#xff0c;远远超出了许多企业的防御能力。DDoS攻击导致的网站性能问题如页面加载缓慢、频繁的504错误等现象&…...

【AI系统】Tensor Core 架构演进

自 Volta 架构时代起&#xff0c;英伟达的 GPU 架构已经明显地转向深度学习领域的优化和创新。2017 年&#xff0c;Volta 架构横空出世&#xff0c;其中引入的张量核心&#xff08;Tensor Core&#xff09;设计可谓划时代之作&#xff0c;这一设计专门针对深度学习计算进行了优…...

React前端框架基础知识详解

React 是由 Facebook 推出的一个用于构建用户界面的 JavaScript 库&#xff0c;现已成为前端开发中最流行的框架之一。React 的核心理念是通过组件化的方式构建用户界面&#xff0c;提升代码的可维护性和复用性。本文将为大家详细介绍 React 框架的基础知识&#xff0c;并带你快…...

Python学习——猜拳小游戏

import random player int(input(“请输入&#xff1a;剪刀 0&#xff0c;石头 1&#xff0c;布2”)) computer random.randint(0,2)# print(“玩家输入的是%d&#xff0c;电脑输入的是%d” %(player,computer)) 用于测试 if (player 0) and (computer 0) or (player 1) a…...

Spring:AOP通知类型

我们先来回顾下AOP通知: AOP通知描述了抽取的共性功能&#xff0c;根据共性功能抽取的位置不同&#xff0c;最终运行代码时要将其加入到合理的位置 通知具体要添加到切入点的哪里? 共提供了5种通知类型: 前置通知后置通知环绕通知(重点)返回后通知(了解)抛出异常后通知(了…...

【公益接口】不定时新增接口,仅供学习

文章日期&#xff1a;2024.11.24 使用工具&#xff1a;Python 文章类型&#xff1a;公益接口 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 AES解密处理&#xff08;直接解密即可&#xff09;&#xff08;crypto-js.js 标准算法&#xff…...

php 导出excel 一个单元格 多张图片

public function dumpData(){error_reporting(0); // 禁止错误信息输出ini_set(display_errors, 0); // 不显示错误$limit $this->request->post(limit, 20, intval);$offset $this->request->post(offset, 0, intval);$page floor($offset / $limit) 1 ;$wh…...

Docker3:docker基础1

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…...

18. 【.NET 8 实战--孢子记账--从单体到微服务】--记账模块--账本

这一篇我们来一起为账本功能编写代码。账本功能的代码很简单&#xff0c;就是一些简单的CURD操作。 一、需求 我们先来看一下需求&#xff1a; 编号需求说明1新增账本1. 账本名称不能和用户已有的账本名称重复2删除账本1. 存在收支记录的账本不能删除3修改账本1. 修改的账本…...

GPT1.0 和 GPT2.0 的联系与区别

随着自然语言处理技术的飞速发展&#xff0c;OpenAI 提出的 GPT 系列模型成为了生成式预训练模型的代表。作为 GPT 系列的两代代表&#xff0c;GPT-1 和 GPT-2 虽然在架构上有着继承关系&#xff0c;但在设计理念和性能上有显著的改进。本文将从模型架构、参数规模、训练数据和…...

在 Taro 中实现系统主题适配:亮/暗模式

目录 背景实现方案方案一&#xff1a;CSS 变量 prefers-color-scheme 媒体查询什么是 prefers-color-scheme&#xff1f;代码示例 方案二&#xff1a;通过 JavaScript 监听系统主题切换 背景 用Taro开发的微信小程序&#xff0c;需求是页面的UI主题想要跟随手机系统的主题适配…...

uni-app 界面TabBar中间大图标设置的两种方法

一、前言 最近写基于uni-app 写app项目的时候&#xff0c;底部导航栏 中间有一个固定的大图标&#xff0c;并且没有激活状态。这里记录下实现方案。效果如下&#xff08;党组织这个图标&#xff09;&#xff1a; 方法一&#xff1a;midButton的使用 官方文档&#xff1a;ta…...

leetcode 无重复字符的最长子串

3. 无重复字符的最长子串 已解答 中等 相关标签 相关企业 提示 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串的长度。 提示&#xff1a; 0 < s.length < 5 * 104s 由英文字母、数字、符号和空格组成 class Solution:def lengthOfLongest…...

【C++习题】14.滑动窗口_找到字符串中所有字母异位词

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 438. 找到字符串中所有字母异位词 题目描述&#xff1a; 解法 暴力解法&#xff1a; 字母排序后运用滑动窗口解题。 滑动窗口哈希表&#xff1a; 我们可以优化一下&am…...

matplotlib知识

问题与解决 1.module backend_interagg has no attribute FigureCanvas问题 Matplotlib 后端不兼容: matplotlib 使用的后端&#xff08;如 backend_interagg&#xff09;可能与当前环境不匹配或未正确加载。 在代码中显式设置一个兼容的后端&#xff0c;例如 TkAgg、Qt5Ag…...

如何在ubuntu上调试core dump

启用core dump 确认ulimit 状态 ulimit -c 如果输出是0&#xff0c;表示core dump被禁用了 运行 ulimit -c unlimited 再次运行 ulimit -c 确认输出是ulimited 设置core dump路径和文件名格式 下面命令表示设置core dump文件在当前目录&#xff08;%e表示程序名&#x…...

Spring Boot教程之五:在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序

在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序 IntelliJ IDEA 是一个用 Java 编写的集成开发环境 (IDE)。它用于开发计算机软件。此 IDE 由 Jetbrains 开发&#xff0c;提供 Apache 2 许可社区版和商业版。它是一种智能的上下文感知 IDE&#xff0c;可用于在各种应用程序…...

排序算法1

排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要访问外存。 常见的内部…...

vector, list 模拟实现

vector 实现 成员属性/迭代器 template<class T> class vector { public:typedef T* iterator;typedef const T* const_iterator;iterator begin() {return _first; }iterator end() {return _end; }const_iterator begin() const {return _first; }const_iterator end…...

中国近代传奇战役

军事战略层面的传奇战役 孟良崮战役&#xff1a;1947年5月&#xff0c;陈毅、粟裕指挥华东野战军在山东孟良崮地区对国民党军进行的一次大规模山地运动歼灭战。此役&#xff0c;我军出其不意地对国民党最强大的王牌之首第七十四师开战&#xff0c;并将其全歼。战役中&#xff…...

微信小程序页面配置详解:从入门到精通

微信小程序页面配置详解:从入门到精通 引言 随着移动互联网的飞速发展,微信小程序作为一种新兴的应用形式,因其便捷性和丰富的功能而受到广泛欢迎。在小程序的开发过程中,页面配置是至关重要的一环。本文将深入探讨微信小程序的页面配置,帮助开发者从基础到高级逐步掌握…...

C#基础题

6.在屏幕上输出如下所示数列&#xff1a;1 1 2 3 5 8 13 21……an(an<10000) 7.求任意两个整数之间所有整数的平方和&#xff1f;&#xff08;要求从键盘输入任意两个整数&#xff0c;调用已定义函数求和&#xff09; 8.将一个二维数组行和列元素互换&#xff0c;存…...