Linux驱动开发:SPI驱动开发原理
前言
本文章是根据韦东山老师的教学视频整理的学习笔记https://video.100ask.net/page/1712503
SPI 通信协议采用同步全双工传输机制,拓扑架构支持一主多从连接模式,这种模式在实际应用场景中颇为高效。其有效传输距离大致为 10m ,传输速率处于 1 - 70Mbps 区间,能够满足多种场景的速率要求。SPI 采用大端传输方式,电气类型为 TTL 电平标准,在常见数字电路中具有良好的兼容性。
一、SPI硬件框架
SPI主要由四条信号线组成,分别是 SCK、MOSI、MISO 和 SS。
1、串行时钟线(SCK)
- 功能:SCK 是由主设备产生的时钟信号,用于同步主设备和从设备之间的数据传输。主设备通过控制 SCK 的频率来决定数据传输的速率,每一个时钟脉冲对应一位数据的传输。
- 工作原理:在时钟信号的上升沿或下降沿,主设备和从设备会进行数据的发送和接收操作。具体是上升沿还是下降沿进行数据操作,取决于 SPI 的工作模式(由时钟极性 CPOL 和时钟相位 CPHA 决定)。
2、主输出从输入线(MOSI)
- 功能:MOSI用于主设备向从设备发送数据。。当主设备需要向从设备传输数据时,它会将数据通过 MOSI 线逐位发送出去,从设备在相应的时钟信号控制下接收这些数据。
- 工作原理:在 SCK 的有效沿(上升沿或下降沿),主设备将待发送的数据位放到 MOSI 线上,从设备在同一时刻读取该线上的数据位。这样,随着 SCK 时钟信号的不断变化,主设备就可以将数据依次发送给从设备。
3、主输入从输出线(MISO)
- 功能:MISO 用于从设备向主设备发送数据。当从设备需要将数据反馈给主设备时,它会将数据通过 MISO 线逐位发送出去,主设备在相应的时钟信号控制下接收这些数据。
- 工作原理:与 MOSI 类似,在 SCK 的有效沿,从设备将待发送的数据位放到 MISO 线上,主设备在同一时刻读取该线上的数据位。通过这种方式,从设备可以将数据传输给主设备。
4、从设备选择线(SS)
- 功能:SS 线用于主设备选择要与之通信的从设备。SPI 支持一主多从的拓扑结构,主设备通过拉低特定从设备的 SS 线来选中该从设备,使其进入工作状态,准备进行数据传输。
- 工作原理:在 SPI 通信中,每个从设备都有一个独立的 SS 线,当主设备需要与某个从设备通信时,将该从设备的 SS 线拉低(通常为低电平有效),其他从设备的 SS 线保持高电平。被选中的从设备会响应主设备的时钟信号和数据传输请求,而未被选中的从设备则处于空闲状态,不参与数据传输。
二、SPI协议
SPI四种模式
时钟极性(CPOL)定义了时钟空闲状态电平
- CPOL=0,SCK 信号在空闲状态(即没有数据传输时)保持低电平。在这种情况下,SCK 信号的有效沿为上升沿(从低电平到高电平的跳变),数据通常在上升沿被采样。
- CPOL=1,SCK 信号在空闲状态保持高电平。此时,SCK 信号的有效沿为下降沿(从高电平到低电平的跳变),数据通常在下降沿被采样。
时钟相位(CPHA)定义了数据的采集时间
- CPHA=0,在SCK的第一个跳变沿(上升沿或下降沿)进行数据采样。
- CPHA=1,在SCK的第二个跳变沿(上升沿或下降沿)进行数据采样。
表1 SPI四种工作模式
模式 | CPOL | CPHA | 描述 |
mode0 | 0 | 0 | ![]() |
mode1 | 0 | 1 | ![]() |
mode2 | 1 | 0 | ![]() |
mode3 | 1 | 1 | ![]() |
三、SPI总线设备驱动模型
1、平台总线驱动模型
先来回顾一下平台总线驱动模型。
平台总线驱动模型将驱动程序分成两部分:
一部分注册一个platform_driver结构体;
另一部分注册一个platform_device结构体
- 可以使用C文件注册platform_device。
- 也可以使用设备树创建一个节点,内核解析设备树时注册platform_device。
匹配机制概述
在 Linux 内核中,platform_bus_type
负责管理平台设备(platform_device
)和平台驱动(platform_driver
)的匹配过程。
platform_bus_type
定义了一个 match
函数,当有新的平台设备或平台驱动注册到系统时,内核会调用这个 match
函数来判断设备和驱动是否匹配。如果匹配成功,内核会调用驱动的 probe
函数来初始化设备。
platform_match源码如下所示:
static int platform_match(struct device *dev, struct device_driver *drv)
{struct platform_device *pdev = to_platform_device(dev);struct platform_driver *pdrv = to_platform_driver(drv);/* When driver_override is set, only bind to the matching driver */if (pdev->driver_override)return !strcmp(pdev->driver_override, drv->name);/* Attempt an OF style match first */if (of_driver_match_device(dev, drv))return 1;/* Then try ACPI style match */if (acpi_driver_match_device(dev, drv))return 1;/* Then try to match against the id table */if (pdrv->id_table)return platform_match_id(pdrv->id_table, pdev) != NULL;/* fall-back to driver name match */return (strcmp(pdev->name, drv->name) == 0);
}
platform_match函数会按照以下顺序来尝试匹配设备和驱动:
- 检查设备的driver_override字段;
- 尝试使用设备树(of)风格匹配;
- 尝试使用ACPI风格匹配;
- 尝试依据驱动的id_table进行匹配
- 若前面的匹配都失败了,就使用设备和驱动的名称进行匹配。
2、SPI数据结构
前面的硬件框架可以看出,SPI子系统涉及到2类硬件:SPI控制器、SPI设备。
在SPI总线设备驱动模型中,spi_master、spi_device和spi_driver是三个核心的数据结构和概念,它们共同协作实现对SPI设备的管理和驱动。
spi_master结构体
spi_master代表SPI主控制器,它是系统中负责管理SPI总线并与SPI从设备进行通信的硬件实体。在Linux内核中,它抽象魏一个spi_master结构体,用来描述和控制 SPI 主机控制器的各种属性与操作,里面最重要的成员是transfer函数指针。
struct spi_master {struct device dev;struct list_head list;/* other than negative (== assign one dynamically), bus_num is fully* board-specific. usually that simplifies to being SOC-specific.* example: one SOC has three SPI controllers, numbered 0..2,* and one board's schematics might show it using SPI-2. software* would normally use bus_num=2 for that controller.*/s16 bus_num;/* chipselects will be integral to many controllers; some others* might use board-specific GPIOs.*/u16 num_chipselect;/* some SPI controllers pose alignment requirements on DMAable* buffers; let protocol drivers know about these requirements.*/u16 dma_alignment;/* spi_device.mode flags understood by this controller driver */u16 mode_bits;/* bitmask of supported bits_per_word for transfers */u32 bits_per_word_mask;
#define SPI_BPW_MASK(bits) BIT((bits) - 1)
#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0U : (BIT(bits) - 1))
#define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1))/* limits on transfer speed */u32 min_speed_hz;u32 max_speed_hz;/* other constraints relevant to this driver */u16 flags;
#define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */
#define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */
#define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */
#define SPI_MASTER_MUST_RX BIT(3) /* requires rx */
#define SPI_MASTER_MUST_TX BIT(4) /* requires tx *//** on some hardware transfer / message size may be constrained* the limit may depend on device transfer settings*/size_t (*max_transfer_size)(struct spi_device *spi);size_t (*max_message_size)(struct spi_device *spi);/* I/O mutex */struct mutex io_mutex;/* lock and mutex for SPI bus locking */spinlock_t bus_lock_spinlock;struct mutex bus_lock_mutex;/* flag indicating that the SPI bus is locked for exclusive use */bool bus_lock_flag;/* Setup mode and clock, etc (spi driver may call many times).** IMPORTANT: this may be called when transfers to another* device are active. DO NOT UPDATE SHARED REGISTERS in ways* which could break those transfers.*/int (*setup)(struct spi_device *spi);/* bidirectional bulk transfers** + The transfer() method may not sleep; its main role is* just to add the message to the queue.* + For now there's no remove-from-queue operation, or* any other request management* + To a given spi_device, message queueing is pure fifo** + The master's main job is to process its message queue,* selecting a chip then transferring data* + If there are multiple spi_device children, the i/o queue* arbitration algorithm is unspecified (round robin, fifo,* priority, reservations, preemption, etc)** + Chipselect stays active during the entire message* (unless modified by spi_transfer.cs_change != 0).* + The message transfers use clock and SPI mode parameters* previously established by setup() for this device*/int (*transfer)(struct spi_device *spi,struct spi_message *mesg);/* called on release() to free memory provided by spi_master */void (*cleanup)(struct spi_device *spi);/** Used to enable core support for DMA handling, if can_dma()* exists and returns true then the transfer will be mapped* prior to transfer_one() being called. The driver should* not modify or store xfer and dma_tx and dma_rx must be set* while the device is prepared.*/bool (*can_dma)(struct spi_master *master,struct spi_device *spi,struct spi_transfer *xfer);/** These hooks are for drivers that want to use the generic* master transfer queueing mechanism. If these are used, the* transfer() function above must NOT be specified by the driver.* Over time we expect SPI drivers to be phased over to this API.*/bool queued;struct kthread_worker kworker;struct task_struct *kworker_task;struct kthread_work pump_messages;spinlock_t queue_lock;struct list_head queue;struct spi_message *cur_msg;bool idling;bool busy;bool running;bool rt;bool auto_runtime_pm;bool cur_msg_prepared;bool cur_msg_mapped;struct completion xfer_completion;size_t max_dma_len;int (*prepare_transfer_hardware)(struct spi_master *master);int (*transfer_one_message)(struct spi_master *master,struct spi_message *mesg);int (*unprepare_transfer_hardware)(struct spi_master *master);int (*prepare_message)(struct spi_master *master,struct spi_message *message);int (*unprepare_message)(struct spi_master *master,struct spi_message *message);int (*spi_flash_read)(struct spi_device *spi,struct spi_flash_read_message *msg);bool (*flash_read_supported)(struct spi_device *spi);/** These hooks are for drivers that use a generic implementation* of transfer_one_message() provied by the core.*/void (*set_cs)(struct spi_device *spi, bool enable);int (*transfer_one)(struct spi_master *master, struct spi_device *spi,struct spi_transfer *transfer);void (*handle_err)(struct spi_master *master,struct spi_message *message);/* gpio chip select */int *cs_gpios;/* statistics */struct spi_statistics statistics;/* DMA channels for use with core dmaengine helpers */struct dma_chan *dma_tx;struct dma_chan *dma_rx;/* dummy data for full duplex devices */void *dummy_rx;void *dummy_tx;int (*fw_translate_cs)(struct spi_master *master, unsigned cs);
};
spi_device结构体
spi_device代表一个具体的 SPI 从设备,它连接到 SPI 总线上,是 SPI 通信的目标设备。在 Linux 内核中,它抽象为一个spi_device结构体,用于描述 SPI 从设备的各种属性。
struct spi_device {struct device dev;struct spi_master *master;u32 max_speed_hz;u8 chip_select;u8 bits_per_word;u16 mode;
#define SPI_CPHA 0x01 /* clock phase */
#define SPI_CPOL 0x02 /* clock polarity */
#define SPI_MODE_0 (0|0) /* (original MicroWire) */
#define SPI_MODE_1 (0|SPI_CPHA)
#define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
#define SPI_CS_HIGH 0x04 /* chipselect active high? */
#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */
#define SPI_3WIRE 0x10 /* SI/SO signals shared */
#define SPI_LOOP 0x20 /* loopback mode */
#define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */
#define SPI_READY 0x80 /* slave pulls low to pause */
#define SPI_TX_DUAL 0x100 /* transmit with 2 wires */
#define SPI_TX_QUAD 0x200 /* transmit with 4 wires */
#define SPI_RX_DUAL 0x400 /* receive with 2 wires */
#define SPI_RX_QUAD 0x800 /* receive with 4 wires */int irq;void *controller_state;void *controller_data;char modalias[SPI_NAME_SIZE];int cs_gpio; /* chip select gpio *//* the statistics */struct spi_statistics statistics;/** likely need more hooks for more protocol options affecting how* the controller talks to each chip, like:* - memory packing (12 bit samples into low bits, others zeroed)* - priority* - drop chipselect after each word* - chipselect delays* - ...*/
};
spi_driver结构体
spi_driver代表 SPI 设备的驱动程序,它实现了对 SPI 从设备的具体操作和功能。在 Linux 内核中,它抽象为一个spi_driver结构体,包含了驱动程序的各种回调函数。
struct spi_driver {const struct spi_device_id *id_table;int (*probe)(struct spi_device *spi);int (*remove)(struct spi_device *spi);void (*shutdown)(struct spi_device *spi);struct device_driver driver;
};
三者关系
spi_master负责管理 SPI 总线,为spi_device提供通信的基础;spi_device代表具体的 SPI 从设备,通过spi_master注册到系统中;spi_driver则负责驱动spi_device,通过与spi_device匹配后,实现对设备的具体操作和数据传输。它们共同构成了 Linux 内核中 SPI 总线设备驱动模型的核心部分。
3、SPI驱动框架
在 Linux 系统中,SPI 控制器通常是通过平台总线驱动模型进行创建和管理的,而 SPI 设备则是基于 SPI 总线驱动模型来创建和操作的。
相关文章:
Linux驱动开发:SPI驱动开发原理
前言 本文章是根据韦东山老师的教学视频整理的学习笔记https://video.100ask.net/page/1712503 SPI 通信协议采用同步全双工传输机制,拓扑架构支持一主多从连接模式,这种模式在实际应用场景中颇为高效。其有效传输距离大致为 10m ,传输速率…...
Java 通过 JNI 调用 C++ 动态库的完整流程
介绍使用 JNI 调用 C 编写的动态链接库的全过程。 示例环境 项目说明JDK8C 编译器Visual Studio 2019Java 开发工具IntelliJ IDEA 2021.3操作系统Windows 10 Java 项目结构概览 编写 Java 类 在 org.jni.nativejni 包下创建类 HelloWorldJni.java: package org…...
oracle 11g密码长度和复杂度查看与设置
一 查看当前的密码复杂度设置 SELECT * FROM dba_profiles WHERE resource_name PASSWORD_VERIFY_FUNCTION; LIMIT表示分配给该 PROFILE 的密码验证函数名称。如果为 NULL,表示未设置密码验证函数。 #查看是否有相关密码验证函数 select object_name from dba…...
1021 Deepest Root
1021 Deepest Root 分数 25 全屏浏览 切换布局 作者 CHEN, Yue 单位 浙江大学 A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest…...
1. 三带一
所谓“三带一”牌型,即四张手牌中,有三张牌一样,另外一张不与其他牌相同,换种说法,四张手牌经过重新排列后,可以组成 AAABAAAB 型。 输入格式 第一行输入一个整数 TT ,代表斗地主的轮数。 接…...
pytorch计算图Computation_graph是什么
文章目录 一、AI系统中的计算图(宏观)二、动态计算图(微观)2.1 张量计算图2.2 计算图的定义2.3 节点类型2.4 计算图的动态性2.5 计算图的正向传播是立即执行的2.6 计算图在反向传播后立即销毁2.7 计算图中的Function2.8 计算图与反…...
HTML5元素
HTML5的<section>元素和<article>元素 <section>元素定义文档中的一部分,着重于对页面内容进行分块或者分段,通常可以分为引言、内容和联系人信息等几个部分。 <section><h1>WWF</h1><p>WWF 是世界自然基金…...
单reactor实战
前言:reactor作为一种高性能的范式,值得我们学习 本次目标 实现一个基于的reactor 具备echo功能的服务器 核心组件 Reactor本身是靠一个事件驱动的框架,无疑引出一个类似于moduo的"EventLoop "以及boost.asio中的context而言,不断…...
【C#知识点详解】LinkedList<T>储存结构详解
今天来介绍一下LinkedList<T>的内部结构,说不多说直接开始。 内部数据 LinkedList是一个双向链表结构的容器,其内部为非连续的内存空间。LinkedList包含的主要成员示例如下: //起始LinkedListNode节点 internal LinkedListNode<T&g…...
智能穿梭车在快消行业的融合升级:效率革命与数据智能的双重赋能
快消品牌(FMCG)的核心挑战在于高频周转、海量SKU、短时效性,而智能穿梭车的技术进化(如AI调度、5G通信、柔性载具)与快消行业的业务需求(如全渠道订单履约、动态库存优化)深度结合,正…...
(二)链表结构
备注:根据coderwhy数据结构与算法课程进行笔记总结 1.数组缺点: 数组创建通常需要申请一段连续的内存空间,且大小固定,因此当前数组不能满足容量需求时,就需要扩容。在数组开头或中间位置插入数据成本很高࿰…...
oracle json笔记
文章目录 json_valuejson_value示例json_value on error如何使用 TODO json_queryjson_query示例 json_tablejson_table 示例 json_existsjson_exists示例json_exists报错 ORA-40458: 在谓词外部使用了 JSON_EXISTS json_objectjson_arrayjson_mergepatchjson_objectaggjson_ar…...
c编译和c++编译有什么区别?
文章目录 c编译和c编译有什么区别多态函数重载虚函数表 vtable 输入输出同步类型检查模板和特化链接 C 标准库 C 能编译 C 的代码吗? c编译和c编译有什么区别 多态 函数重载 C 支持多个同名函数(参数不同),这是编译期多态 编译…...
【Mysql】主从复制和读写分离
一、定义 1、什么是读写分离? 在主库master上负责处理事务性写入操作,在从库slave上负责处理查询操作,并通过主从复制将主库上的数据同步给从库。 2、为什么要读写分离? 从集中到分布,最基本的一个需求不是数据存储的…...
泛目录排名——深入理解与优化 SEO:提升网站可见性的关键策略
https://www.zhanqun.xin/ 在数字化时代,互联网上的信息呈爆炸式增长。对于企业和网站运营者而言,如何让自己的网站在海量的网络内容中脱颖而出,吸引目标受众的关注,成为了一项至关重要的挑战。搜索引擎优化(SEO&#…...
汇丰eee2
聚合和继承有什么样的优点和区别,什么时候决定用,现实开发中,选择哪一种去使用? 聚合的优点: 灵活性: 聚合是一种弱耦合关系,被聚合对象可以独立存在,可以灵活地替换或修改被聚合对…...
C#网络编程(Socket编程)
文章目录 0、写在前面的话1、Socket 介绍1.1 Socket是什么1.2 Socket在网络中的位置 2、C# 中的Socket参数2.1 超时控制参数2.2 缓冲区参数2.3 UDP专用参数 3、C# 中的Socket API3.1 Socket(构造函数)3.1.1 SocketType3.1.2 ProtocolType3.1.3 AddressFa…...
使用Python的Schedule库实现定时任务,并传递参数给任务函数
哈喽,大家好,我是木头左! 本文将详细介绍如何使用schedule库来创建定时任务,并展示如何向任务函数传递参数。 安装Schedule库 需要安装schedule库。你可以使用以下命令通过pip进行安装: pip install schedule基本用法 schedule库的基本用法非常简单。你可以通过调用sch…...
Unity Input 2023 Release-Notes
🌈Input 2023 Release-Notes 版本更新内容2023.2.17Input: Crash on InputDeviceIOCTL when closing Unity editor(UUM-10774)2023.2.16Input: Crash on InputDeviceIOCTL when closing Unity editor(UUM-10774)2023.2.15Input: Crash on InputDeviceIOCTL when clo…...
IP查询能够帮助企业进行数字化转型
企业如今正面临着用户行为碎片化、市场竞争白热化的挑战。那么企业要如何从海量网络数据中精准捕捉用户需求就十分重要了。而IP查询技术也正帮助越来越多的企业在精准营销、风险防控、合规运营等领域开辟新的增长空间。 https://www.ipdatacloud.com/?utm-sourceLMN&utm-…...
Nginx漏洞复现
vulhub起靶场 Nginx 文件名逻辑漏洞(CVE-2013-4547) 上传1.gif,内容为 <?php phpinfo();?> http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php访问文件位置,这里0x00要改包 先访问/uploadfiles/1.gif a.php&…...
数据结构|排序算法(二)插入排序 希尔排序
一、插入排序 1.算法思想 插入排序(Insertion Sort)是一种简单的排序算法,其基本思想是:将待排序的元素插入到已经有序的序列中,从而逐步构建有序序列。 具体过程如下: 把待排序的数组分为已排序和未排…...
OpenBMC:BmcWeb 处理http请求5 检查权限
OpenBMC:BmcWeb 处理http请求4 处理路由对象-CSDN博客 在通过url获取了路由对象后,如果该请求是有session的,那么下一步需要检查权限 1.validatePrivilege调用时传入了一个lambda(1)做为回调 validatePrivilege(req, asyncResp, rule,[req, asyncResp, &rule, params =…...
CentOS 系统磁盘扩容并挂载到根目录(/)的详细步骤
在使用 CentOS 系统时,经常会遇到需要扩展磁盘空间的情况。例如,当虚拟机的磁盘空间不足时,可以通过增加磁盘容量并将其挂载到根目录(/)来解决。以下是一个完整的操作流程,详细介绍了如何将新增的 10G 磁盘…...
Axure RP 9 for Mac 交互原型设计 安装教程@[TOC](文章目录)
Axure RP 9 for Mac 交互原型设计 安装教程TOC 一、介绍 Axure RP 9是一款功能强大的原型设计和协作工具。它不仅能够帮助用户快速创建出高质量的原型设计,还能促进团队成员之间的有效协作,从而极大地提高数字产品开发的效率和质量。拥有直观易用的界面…...
每日一题(小白)暴力娱乐篇19
样例: 6 1 1 4 5 1 4 输出: 56 66 52 44 54 64 分析题意可以得知,就是接收一串数字,将数字按照下标每次向右移动一位(末尾循环到第一位),每次移动玩计算一下下标和数字的乘积且累加。 ①接收…...
LeetCode 第53题:最大子数组和
题目描述: 给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。 示例1: 输入:nums [-2,1,-3,4,-1,2,1,-5,4] 输出ÿ…...
顺序表:从数组到高效数据管理的进化之路
一、线性表:数据结构的 “基础骨架” 在数据结构的世界里,线性表是最基础的结构之一。它是由n个具有相同特性的数据元素组成的有限序列,就像一列整齐排列的士兵,每个元素都有唯一的前驱(除了第一个)和后继…...
TS知识补充第一篇 ✅
目录 1️⃣ any、unknow和never 2️⃣ 函数重载 3️⃣ typeof和keyof(配合构建字典类型的Demo,巨好用‼️) 4️⃣ TS的条件类型 5️⃣ TS的声明合并 一、any、unknow和never any any类型表示一个值可以是任何类型。通常在不确定变量的类型…...
每日一题(小白)模拟娱乐篇18
今天和大家一起玩个小游戏,给小朋友分糖果🍬 由题知就是小朋友每次给左手边的小朋友分一半糖果,一轮下来如果是奇数糖果老师就给他补一个直到所有小朋友拥有相同数量的糖果,问问老师发放了多少糖果。用程序进行模拟的大概思路就是…...
Linux系统学习Day2——在Linux系统中开发OpenCV
一、OpenCV简介 OpenCV(Open Source Computer Vision Library)是一个开源的跨平台计算机视觉和机器学习库,广泛应用于图像处理、视频分析、物体检测等领域。它提供了丰富的算法和高效的工具集,支持C、Python等多种语言,…...
Redisson 实现分布式锁
在平常的开发工作中,我们经常会用到锁,那么锁有什么用呢?锁主要是控制对共享资源的访问顺序,防止多个线程并发操作导致数据不一致的问题。经常可能会听到乐观锁、悲观锁、分布式锁、行锁、表锁等等,那么我们今天总结下…...
(适合中白)数据结构进阶篇——搜索专题(广度优先搜索算法BFS和深度优先搜索算法DFS)
深度优先搜索DFS&广度优先搜索BFS 深度优先搜索广度优先搜索 深度优先搜索 当碰到岔路口时,总是以深度作为前进的关键词,不碰到死胡同就不回头的这种搜索方式被称为深度优先搜索(Depth First Search) 深度优先搜索是一种枚举所有完整路径以遍历所有情…...
SGLang实战问题全解析:从分布式部署到性能调优的深度指南
引言:当高性能推理遇上复杂生产环境 在大型语言模型(LLM)的生产部署中,SGLang以其革命性的RadixAttention和结构化编程能力,正成为越来越多企业的首选推理引擎。然而,当我们将32B/70B级别的大模型部署到实际生产环境时࿰…...
Java大视界:解码航天遥测数据的银河密码——从GB到PB的技术革命
当长征火箭划破苍穹的瞬间,每秒产生的遥测数据足以填满一部4K电影。在这场与星辰对话的征程中,Java大数据生态正扮演着解码宇宙密码的"数字炼金师"。本文将带您穿越三个认知维度,揭示Java技术栈如何重构航天数据分析的底层逻辑。 …...
《C++探幽:STL(string类源码的简易实现(下))》
作者的个人gitee▶️ 作者的算法讲解主页 每日一言:“驿寄梅花,鱼传尺素,砌成此恨无重数。🌸🌸” 接《C探幽:STL(string类源码的简易实现(上))》🔴…...
求线性表的倒数第K项 (数组、头插法、尾插法)
给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字。 输入格式: 输入首先给出一个正整数K,随后是若干非负整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理)…...
rustdesk自建服务器怎么填写客户端配置信息
目录 # id、api、中继都怎么填?rustdesk程序启动后服务不自动启动 # id、api、中继都怎么填? rustdesk程序启动后服务不自动启动 完全退出RudtDesk程序(右下角托盘区有的话,需要右键点退出) 创建windows服务ÿ…...
4月8日日记
今天抖音刷到一个视频 记了一下笔记 想做自媒体,直播,抖音是最大的平台,但是我的号之前因为跟人互喷被封号了 今天想把实名认证转移到新号上,试了一下竟然这次成功了,本以为能开直播了但是 还是因为之前的号有违规记…...
VScode添加python解释器
先安装python扩展 然后点ctrlshiftp搜索python:select,选择解析器(或者也可以直接点左下方的)...
Elasticsearch | ES索引模板、索引和索引别名的创建与管理
关注:CodingTechWork 引言 在使用 Elasticsearch (ES) 和 Kibana 构建数据存储和分析系统时,索引模板、索引和索引别名的管理是关键步骤。本文将详细介绍如何通过 RESTful API 和 Kibana Dev Tools 创建索引模板、索引以及索引别名,并提供具…...
用 Python 造轮子:打造轻量级 HTTP 调试工具
目录 一、为什么需要自建工具? 二、核心功能设计 三、技术选型 四、分步实现 第一步:搭建基础框架 第二步:实现请求转发逻辑 第三步:响应格式化处理 第四步:历史记录存储 五、进阶优化技巧 六、使用示例 七…...
java设计模式-原型模式
原型模式 1、原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并通过拷贝这些原型,创建新的对象 2、原型模式是一种创见性设计模式,允许一个对象再创建另一个可定制的对象,无需知道如何创建的细节。 3、工作…...
【Java设计模式】第9章 原型模式讲解
9. 原型模式 9.1 原型模式讲解 定义:通过拷贝原型实例创建新对象,无需调用构造函数。特点: 创建型模式无需了解创建细节适用场景: 类初始化消耗资源多对象创建过程繁琐(如属性赋值复杂)循环体中需创建大量对象优点: 性能优于直接new简化创建流程缺点: 必须实现clone()…...
Python 快速搭建一个小型的小行星轨道预测模型 Demo
目录 ✅ Demo 目标: 🧪 模型方案选择 方案 1:开普勒 LSTM 混合预测(推荐 💡) 方案 2:全 AI:LSTM 直接拟合轨迹 🚧 环境准备 🔧 示例代码结构ÿ…...
【AI】Ragflow构建本地知识库
https://github.com/infiniflow/ragflow/blob/main/README_zh.md DeepSeek搭建的本地知识库很呆?不符合自己的预期?看完这个视频你就明白了!这样部署吊打其他的本地部署!跟着教程来,不怕学不会!_哔哩哔哩_…...
【Django】教程-12-柱状图
【Django】教程-1-安装创建项目目录结构介绍 【Django】教程-2-前端-目录结构介绍 【Django】教程-3-数据库相关介绍 【Django】教程-4-一个增删改查的Demo 【Django】教程-5-ModelForm增删改查规则校验【正则钩子函数】 【Django】教程-6-搜索框-条件查询前后端 【Django】教程…...
市政消防栓智能监控管理系统(Axure高保真原型)
在城市的运转体系中,市政消防栓扮演着无可替代的关键角色,作为城市公共安全基础设施的核心,它是火灾扑救时的关键水源保障,其重要性不言而喻。当火灾这头 “猛兽” 突然来袭,市政消防栓就是那道阻止火势蔓延、守护生命…...
机器学习课堂6交叉熵代价函数的逻辑回归模型
代码 # 2-10交叉熵代价函数的逻辑回归模型 import pandas as pd import numpy as np import matplotlib.pyplot as plt# 参数设置 iterations 1000 # 迭代次数 learning_rate 0.1 # 学习率 m_train 250 # 训练样本数量# 读入酒驾检测数据集 df pd.read_csv(alcohol_d…...
华为ar1200修改con口密码
<Huawei> <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]user-interface console 0 进入端口 [Huawei-ui-console0]authentication-mode pass 以pass模式登录 [Huawei-ui-console0]set authentication password cipher …...