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

Linux 驱动开发步骤及 SPI 设备驱动移植示例

Linux 驱动开发的一般步骤

  1. 硬件了解:深入研究目标硬件设备的工作原理、寄存器映射、电气特性、中断机制等。例如,若开发网卡驱动,需清楚网卡如何与网络介质交互、数据包的收发流程、硬件缓冲区的管理等。只有透彻理解硬件,才能编写出与之适配的驱动程序。
  2. 创建驱动框架:依据 Linux 内核提供的驱动模型,搭建驱动的基本结构。对于字符设备驱动,需定义struct cdev结构体,并实现其初始化函数、设备注册与注销函数等。以简单的 LED 驱动为例,要创建一个包含 LED 初始化、控制等操作的结构体,以及对应的初始化和注册函数,将 LED 设备与内核框架关联起来。
  3. 实现驱动功能:完成硬件初始化,包括设置硬件寄存器使其进入工作状态,如配置 SPI 控制器的时钟频率、数据位宽等。进行寄存器读写操作,通过内核提供的函数(如ioread、iowrite)与硬件寄存器交互,实现数据传输和设备控制。处理设备中断,若设备支持中断,编写中断处理函数,在中断发生时及时响应并处理相关事务,如网卡收到新数据包时触发中断,中断处理函数负责将数据从硬件缓冲区读取到内核缓冲区。
  4. 测试与调试:使用insmod或modprobe命令加载驱动模块,观察系统日志(dmesg命令),查看驱动加载过程中是否有错误信息。编写测试应用程序,从用户空间调用驱动提供的接口,验证驱动功能是否正常。例如,对于字符设备驱动,测试程序可使用open、read、write、close等系统调用来操作设备。利用内核调试工具(如kgdb),设置断点、单步执行等,深入分析驱动运行时的问题,排查错误根源。

SPI 设备驱动移植示例

        以将 SPI 设备驱动移植到基于 Linux 系统的嵌入式开发板为例,假设开发板使用的芯片为 [具体芯片型号],目标 SPI 设备为 [SPI 设备名称],如 SPI Flash。

  1. 硬件连接确认:检查开发板上 SPI 控制器与 SPI 设备的物理连接,包括 SPI 时钟线(SCK)、主机输出从机输入线(MOSI)、主机输入从机输出线(MISO)、从机选择线(CS)等,确保连接正确且稳定。例如,SPI Flash 的 CS 引脚需连接到开发板 SPI 控制器的对应 GPIO 引脚,以便主机选择该从机设备。
  2. 内核配置:进入内核配置界面(通常通过make menuconfig命令),确保内核已启用 SPI 子系统相关选项。在配置菜单中找到 “Device Drivers” -> “SPI support”,确保其被选中,若 SPI 控制器有特定的驱动选项(如针对开发板芯片的 SPI 控制器驱动),也需一并选中。例如,若开发板使用的是 [芯片厂商] 的 SPI 控制器,需确保该厂商对应的 SPI 驱动选项被使能。
  3. 添加设备树描述:在设备树文件(通常位于arch/arm/boot/dts目录下,具体文件名根据开发板型号而定)中添加 SPI 设备的描述信息。例如:
 

spi_device: spi@[SPI控制器地址] {

compatible = "vendor,spi - device - name";

spi - master - num = <[SPI控制器编号]>;

cs - gpios = <&gpio[GPIO端口号] [GPIO引脚号] 0>;

spi - mode = <[SPI模式,如0、1、2、3]>;

spi - clock - freq = <[SPI时钟频率,如10000000]>;

#address - cells = <1>;

#size - cells = <0>;

reg = <[SPI设备片内寄存器地址,若有]>;

};

上述代码中,compatible字段用于匹配驱动程序,cs - gpios指定从机选择引脚,spi - mode设置 SPI 模式,spi - clock - freq设定时钟频率等。

4. 编写 SPI 设备驱动代码

  • 创建驱动模块框架:定义 SPI 设备驱动结构体,包含设备操作函数指针等。例如:
 

#include <linux/module.h>

#include <linux/spi/spi.h>

static const struct spi_device_id spi_device_ids[] = {

{"vendor,spi - device - name", 0},

{}

};

MODULE_DEVICE_TABLE(spi, spi_device_ids);

static struct spi_driver spi_device_driver = {

.driver = {

.name = "spi - device - driver",

.owner = THIS_MODULE,

},

.id_table = spi_device_ids,

.probe = spi_device_probe,

.remove = spi_device_remove,

};

  • 实现probe函数:在设备探测函数中,完成 SPI 设备的初始化和注册等操作。例如:
 

static int spi_device_probe(struct spi_device *spi)

{

int ret;

// 分配设备私有数据结构体

struct spi_device_private *priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);

if (!priv)

return -ENOMEM;

spi_set_drvdata(spi, priv);

// 配置SPI设备,如设置时钟频率、模式等

spi->mode = SPI_MODE_0;

spi->max_speed_hz = 10000000;

ret = spi_setup(spi);

if (ret) {

dev_err(&spi->dev, "spi setup failed: %d\n", ret);

return ret;

}

// 这里可进一步进行硬件相关的初始化,如读写SPI设备的寄存器进行初始化配置

dev_info(&spi->dev, "SPI device %s probed successfully\n", spi->modalias);

return 0;

}

  • 实现remove函数:在设备移除函数中,进行资源释放等清理操作。例如:
 

static void spi_device_remove(struct spi_device *spi)

{

// 释放设备私有数据结构体等资源

struct spi_device_private *priv = spi_get_drvdata(spi);

// 若有分配的硬件资源(如DMA通道等),在此处释放

dev_info(&spi->dev, "SPI device %s removed\n", spi->modalias);

}

  • 实现设备操作函数:如实现对 SPI 设备的读写函数。例如:
 

static ssize_t spi_device_read(struct file *filp, char __user *buf, size_t count, loff_t *off)

{

struct spi_device *spi = filp->private_data;

struct spi_device_private *priv = spi_get_drvdata(spi);

// 构建SPI传输消息结构体

struct spi_transfer tr = {

.tx_buf = NULL,

.rx_buf = priv->rx_buffer,

.len = count,

};

struct spi_message msg;

spi_message_init(&msg);

spi_message_add_tail(&tr, &msg);

int ret = spi_sync(spi, &msg);

if (ret) {

dev_err(&spi->dev, "SPI read failed: %d\n", ret);

return ret;

}

// 将读取到的数据从内核缓冲区复制到用户空间

ret = copy_to_user(buf, priv->rx_buffer, count);

if (ret) {

dev_err(&spi->dev, "copy to user failed: %d\n", ret);

return -EFAULT;

}

return count;

}

static ssize_t spi_device_write(struct file *filp, const char __user *buf, size_t count, loff_t *off)

{

struct spi_device *spi = filp->private_data;

struct spi_device_private *priv = spi_get_drvdata(spi);

// 将用户空间数据复制到内核缓冲区

int ret = copy_from_user(priv->tx_buffer, buf, count);

if (ret) {

dev_err(&spi->dev, "copy from user failed: %d\n", ret);

return -EFAULT;

}

// 构建SPI传输消息结构体

struct spi_transfer tr = {

.tx_buf = priv->tx_buffer,

.rx_buf = NULL,

.len = count,

};

struct spi_message msg;

spi_message_init(&msg);

spi_message_add_tail(&tr, &msg);

ret = spi_sync(spi, &msg);

if (ret) {

dev_err(&spi->dev, "SPI write failed: %d\n", ret);

return ret;

}

return count;

}

5.编译与测试:将编写好的 SPI 设备驱动代码编译成内核模块(.ko文件),可通过修改驱动目录下的Makefile文件,添加编译规则。例如:

 

obj - m += spi_device_driver.o

KDIR := /lib/modules/$(shell uname - r)/build

PWD := $(shell pwd)

default:

$(MAKE) - C $(KDIR) M=$(PWD) modules

clean:

$(MAKE) - C $(KDIR) M=$(PWD) clean

        然后执行make命令进行编译。编译成功后,使用insmod命令加载驱动模块,通过dmesg命令查看驱动加载信息,确认是否加载成功。接着编写测试应用程序,从用户空间对 SPI 设备进行读写操作,验证驱动功能是否正常。例如:

 

#include <stdio.h>

#include <fcntl.h>

#include <unistd.h>

#include <string.h>

#define SPI_DEVICE_FILE "/dev/spi_device"

int main()

{

int fd = open(SPI_DEVICE_FILE, O_RDWR);

if (fd < 0) {

perror("open spi device failed");

return -1;

}

char write_buf[] = "Hello, SPI device!";

ssize_t write_ret = write(fd, write_buf, strlen(write_buf));

if (write_ret < 0) {

perror("write to spi device failed");

close(fd);

return -1;

}

char read_buf[100];

ssize_t read_ret = read(fd, read_buf, sizeof(read_buf) - 1);

if (read_ret < 0) {

perror("read from spi device failed");

close(fd);

return -1;

}

read_buf[read_ret] = '\0';

printf("Read from SPI device: %s\n", read_buf);

close(fd);

return 0;

}

        编译并运行测试程序,观察 SPI 设备的读写操作是否正确,若有问题,通过调试手段(如打印更多调试信息、使用内核调试工具等)排查解决。

        通过以上步骤,可完成 Linux 驱动开发以及 SPI 设备驱动的移植与测试工作,使 SPI 设备能够在 Linux 系统下正常工作。在实际开发中,需根据具体硬件和应用需求,灵活调整和优化驱动代码。

相关文章:

Linux 驱动开发步骤及 SPI 设备驱动移植示例

Linux 驱动开发的一般步骤 硬件了解&#xff1a;深入研究目标硬件设备的工作原理、寄存器映射、电气特性、中断机制等。例如&#xff0c;若开发网卡驱动&#xff0c;需清楚网卡如何与网络介质交互、数据包的收发流程、硬件缓冲区的管理等。只有透彻理解硬件&#xff0c;才能编…...

直播数据大屏是什么?企业应如何构建直播数据大屏?

目录 一、直播数据大屏是什么&#xff1f; 1. 定义 2. 特点 ​编辑二、企业如何构建直播数据大屏&#xff1f; &#xff08;一&#xff09;明确需求和目标 &#xff08;二&#xff09;数据采集和整合 &#xff08;三&#xff09;选择合适的可视化工具 &#xff08;四&a…...

Vue与Python的深度整合:构建现代Web应用的全栈范式

在前后端分离架构成为行业标准的今天&#xff0c;Vue.js与Python的组合为全栈开发提供了高效且灵活的技术方案。这种组合不仅继承了Vue组件化开发的敏捷性&#xff0c;更借助Python后端框架&#xff08;如Django/Flask&#xff09;的强大生态&#xff0c;实现了从原型设计到生产…...

移动二维矩阵

1、题目描述 小红获得了一个 n行 m 列的二维字符矩阵&#xff0c;现在她要对这个字符矩阵进行向左循环移位。 向左循环移位规则如下&#xff1a;每一行的每一个字母(除了第一个字母)都向左边移动一位。第一行第一个的字母移动到最后一行的最后一个位置&#xff0c;其它行的第一…...

RabbitMq学习(第一天)

文章目录 1、mq(消息队列)概述2、RabbitMQ环境搭建3、java基于AMQP协议操作RabbitMQ4、基于Spring AMQP操作RabbitMQ5、代码中创建队列与交换机①、配置类创建②、基于RabbitListener注解创建 6、RabbitMQ详解①、work模型②、交换机1、Fanout(广播)交换机2、Direct(定向)交换机…...

基于RK3568多功能车载定位导航智能信息终端

基于安卓系统开发集成5G和4G模块&#xff0c;GPS/BD双模定位模块&#xff08;高精度差分惯导&#xff09;、WIFI模块&#xff0c;蓝 牙模块&#xff0c;RFID模块&#xff0c;音频播放&#xff0c;视频信号输入&#xff08;AHD或CVBS&#xff09;模块等多功能车载定位导航智能信…...

Facebook的元宇宙新次元:社交互动如何改变?

科技的浪潮正将我们推向一个全新的时代——元宇宙时代。Facebook&#xff0c;这个全球最大的社交网络平台&#xff0c;已经宣布将公司名称更改为 Meta&#xff0c;全面拥抱元宇宙概念。那么&#xff0c;元宇宙究竟是什么&#xff1f;它将如何改变我们的社交互动方式呢&#xff…...

【上位机——MFC】对话框

对话框的使用 1.添加对话框资源 2.定义一个自己的对话框类(CMyDlg)&#xff0c;管理对话框资源&#xff0c;派生自CDialog或CDialogEx均可 对话框架构 #include <afxwin.h> #include "resource.h"class CMyDlg :public CDialog {DECLARE_MESSAGE_MAP() publi…...

【信息系统项目管理师】法律法规与标准规范——历年考题(2024年-2020年)

手机端浏览☞【信息系统项目管理师】法律法规与标准规范——历年考题&#xff08;2024年-2020年&#xff09; 2024年上半年综合知识【占比分值3′】 42、关于招标投标的描述&#xff0c;不正确的是&#xff08;属于同一集团组织成员的投标人可以按照该组织要求协同投标&#xf…...

【HarmonyOS 5】鸿蒙Web组件和内嵌网页双向通信DEMO示例

【HarmonyOS 5】鸿蒙Web组件和内嵌网页双向通信DEMO示例 一、前言 在 ArkUI 开发中,Web 组件(Web)允许开发者在应用内嵌入网页,实现混合开发场景。 本文将通过完整 DEMO,详解如何通过WebviewController实现 ArkUI 与内嵌网页的双向通信,涵盖 ArkUI 调用网页 JS、网页调…...

var、let、const的区别

1. var 在ES5中&#xff0c;顶层对象的属性和全局变量是等价的&#xff0c;用var声明的变量即是全局变量&#xff0c;也是顶层变量&#xff0c;在浏览器中顶层对象指的是window对象&#xff0c;在node中顶层对象指的是global对象。 console.log(a) // undefined var a 1 cons…...

计算机视觉注意力机制【一】常用注意力机制整理

在做目标检测项目&#xff0c;尤其是基于 YOLOv5 或 YOLOv7 的改进实验时&#xff0c;我发现不同注意力机制对模型性能的提升确实有明显影响&#xff0c;比如提高小目标检测能力、增强特征表达等。但每次找代码都得翻论文、找 GitHub&#xff0c;效率很低。所以我干脆把常见的注…...

交替序列长度的最大值

1、题目描述 给出n个正整数&#xff0c;你可以随意从中挑选一些数字组成 一段序列S&#xff0c;该序列满足以下两个条件&#xff1a; 1.奇偶交替排列&#xff1a;例如&#xff1a;"奇&#xff0c;偶&#xff0c;奇&#xff0c;偶&#xff0c;奇.…" 或者 "偶&a…...

追踪大型语言模型的思想(下)(来自针对Claude的分析)

多步推理 正如我们上面所讨论的&#xff0c;语言模型回答复杂问题的一种方式就是简单地记住答案。例如&#xff0c;如果问“达拉斯所在州的首府是哪里&#xff1f;”&#xff0c;一个“机械”的模型可以直接学会输出“奥斯汀”&#xff0c;而无需知道德克萨斯州&#xff0c;达拉…...

嵌入式通信协议总览篇:万物互联的基石

嵌入式系统的世界,是靠协议“说话”的世界。 在你设计一个智能设备、构建一个工业控制系统、开发一款 IoT 网关时,一个核心问题始终绕不开:**这些设备之间如何“对话”?**答案就是——通信协议。 本篇作为系列第一章,将带你全面理解嵌入式通信协议的全貌,为后续深入学习…...

Android 连接德佟打印机全实例+踩坑

文章目录 1. sdk下载2. 开始开发2.1 打印之前准备工作2.2 打印机是否连接检测2.3 打印框架设计 最近有个需求是要连接 德佟打印机 进行打印相关事宜, 现在就遇到的问题简单阐述一下。 1. sdk下载 我们首先需要在官网下载对应的SDK&#xff0c;地址为&#xff1a;https://www.d…...

TikTok 矩阵运营新手实操保姆级教程 2.0 版本

在当下这个全球化的数字浪潮中&#xff0c;TikTok 这片充满机遇的流量蓝海&#xff0c;正吸引着无数创业者和品牌方争相角逐。而要想在这激烈的竞争中脱颖而出&#xff0c;TikTok 矩阵运营无疑是至关重要的制胜法宝。今天&#xff0c;就给大家送上这份超实用的新手实操教程&…...

WordPress:Locoy.php火车头采集

<?php /* 模块参数列表&#xff1a; post_title 必选 标题 post_content 必选 内容 tag 可选 标签 post_category 可选 分类 post_date 可选 时间 post_excerpt 可选 摘要 post_author 可选 作者 category_description 可选 分类信息 post_cate_meta[name] 可选 自定义分…...

C++ 有哪些标准版本

目录 1.主要分为以下几个版本C98&#xff08;ISO/IEC 14882:1998&#xff09; 第一个国际标准C03&#xff08;ISO/IEC 14882:2003&#xff09;小幅度修订C11&#xff08;ISO/IEC 14882:2011&#xff09;一次重大更新C14&#xff08;ISO/IEC 14882:2014&#xff09;增量改进C17&…...

二、MySQL操作命令汇总

文章目录 二、MySQL操作命令汇总1.数据库操作2.表的增删改查2.1 查表2.2 建表给表添加注释假如表已经存在 2.3 删表2.4 查看表结构2.5 改表 3.简单查询3.1 查询单个字段3.2 查询多个字段3.3 查询所有字段3.4 查询结果去重3.5 查询结果排序3.6 查询结果限制条数3.7 查询分组结果…...

编程日志4.28

队列的链表表示代码 #include<iostream> #include<stdexcept> using namespace std; //队列 类的声明 template<typename T>//1.模板声明&#xff0c;表明Queue类是一个通用的模板类&#xff0c;可以用于存储任何类型的元素T class Queue {//2.Queue类的声…...

Qt 中信号与槽(signal-slot)机制支持 多种连接方式(ConnectionType)

Qt 中信号与槽&#xff08;signal-slot&#xff09;机制支持 多种连接方式&#xff08;ConnectionType&#xff09; Qt 中信号与槽&#xff08;signal-slot&#xff09;机制支持 多种连接方式&#xff08;ConnectionType&#xff09;&#xff0c;用于控制信号发出后如何调用槽…...

Python案例实战《手势识别》

目录 1、效果图2、手势识别关键步骤&#xff08;1&#xff09; 导入必要的库&#xff08;2&#xff09;配置 MediaPipe&#xff08;3&#xff09;启动摄像头&#xff08;4&#xff09;设置手指张开判断的距离阈值&#xff08;5&#xff09;计算手指之间的欧几里得距离&#xff…...

NGINX `ngx_http_charset_module` 字符集声明与编码转换

一、模块定位与功能 ngx_http_charset_module 主要提供两大能力&#xff1a; 响应头声明&#xff1a;在 Content-Type 头部自动添加 ; charsetXXX&#xff0c;告知客户端所用字符集。单向编码转换&#xff1a;在 NGINX 层将一种单字节编码&#xff08;如 koi8-r、windows-125…...

进程与线程详细介绍

目录 一 进程概念 二 进程的组成 2.1 PCB 2.2 数据段 2.3 程序段 三 进程的五大特点 四 进程的创建与销毁 五 线程概念 六 线程特征 七 进程与线程的区别与联系 区别 联系 一 进程概念 进程是程序的一次执行过程&#xff0c;是操作系统进行资源分配和调度的基本单位…...

JAVA中ArrayList的解析

gogogo出发喽&#xff01;让我们来认识一下它吧 什么是ArrayList Java 中的 ArrayList 是 Java 集合框架中的重要类&#xff0c;用于实现动态数组 动态数组&#xff1a;可按需自动扩展或缩小&#xff0c;无需手动管理数组大小。比如不断向 ArrayList 添加元素时&#xff0c;…...

【LLM+Code】Devin PromptTools详细解读

Devin 官网&#xff1a;https://devin.ai/ Prompt 大部分篇幅都是tools的直出的description和parameters的一些信息 其他的包含 Communicatework的一些指导Best PracticesInformation HandlingData SecurityResponse Limitationsplanthink You are Devin, a software engi…...

AI应用开发实战分享

一、前言 30年前的IntelWindows互相绑定&#xff0c;让世界被计算机技术重构了一次&#xff0c;有了程序员这个工种。十几年前iPhone、Android前后脚发布&#xff0c;智能手机和移动App互相绑定&#xff0c;引爆了一个长达十几年的移动互联网大跃进时代。而随着人工智能大模型…...

浅聊find_package命令的搜索模式(Search Modes)

背景 find_package应该算是我们使用最多的cmake命令了。但是它是如何找到上游库的.cmake文件的&#xff1f; 根据官方文档&#xff0c;整理下find_package涉及到的搜索模式。 搜索模式 find_package涉及到的搜索模式有两种&#xff1a;模块模式(Module mode)和配置模式(Conf…...

FPGA图像处理(二)-----彩色图像灰度化

由于fpga实现除法相对复杂&#xff0c;故将除法变为乘法再移位。因此每种方法对图像输入数据均分3步进行&#xff0c;极其有效信号打三拍处理。 timescale 1ns / 1ps // // Description: 彩色图像灰度化 // module image_rgb2gray(input wire clk ,input wir…...

Ultralytics中的YOLODataset和BaseDataset

YOLODataset 和 BaseDataset 是 Ultralytics YOLO 框架中用于加载和处理数据集的两个关键类。 YOLODataset类&#xff08;ultralytics/data/dataset.py&#xff09;继承于 BaseDataset类&#xff08;ultralytics/data/base.py&#xff09; BaseDataset() BaseDataset 是一个…...

Mac 使用 Charles代理生成https服务

在Mac电脑上使用Charles软件通过代理生成HTTPS服务&#xff0c;让手机访问电脑的开发地址&#xff0c;可按以下步骤操作&#xff1a; 一、Charles软件设置 安装与启动Charles&#xff1a;从Charles官网下载并安装Charles软件&#xff0c;之后启动它。开启代理服务 点击菜单栏…...

【PostgreSQL】数据库主从库备份与高可用部署

文章目录 一、架构设计原理二、部署清单示例2.1 StatefulSet配置片段2.2 Service配置三、配置详解3.1 主节点postgresql.conf3.2 从节点配置四、初始化流程4.1 创建复制用户4.2 配置pg_hba.conf五、故障转移示例5.1 自动切换脚本5.2 手动提升从节点六、监控与维护6.1 关键监控指…...

ERP进销存系统源码,SaaS模式多租户ERP管理系统,SpringBoot、Vue、UniAPP技术框架

SaaS ERP管理系统源码&#xff0c;覆盖了整个生产企业所有部门的管理&#xff1a;采购、销售、仓库、生产、财务、质量、OA&#xff1a; ERP源码技术架构&#xff1a;SpringBootVueElementUIUniAPP ERP系统功能清单&#xff1a; 流程处理中心&#xff1a;待审批任务、已审批任…...

Decode rpc invocation failed: null -> DecodeableRpcInvocation

DecodeableRpcInvocation 异常情况解决方法 错误警告官方FAQ 异常情况 记录一下Dubbo调用异常 java.util.concurrent.ExecutionException: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2025-05-07 22:09:5…...

VAE和Stable Diffusion的关系

文章目录 ✅ 简单回顾&#xff1a;什么是 VAE&#xff1f;&#x1f504; Stable Diffusion 和 VAE 的关系&#xff1a;&#x1f3af; 编码器&#xff1a;&#x1f4a5; 解码器&#xff1a; &#x1f914; 那 Stable Diffusion 本身是 VAE 吗&#xff1f;&#x1f9e0; 简要对比…...

stable Diffusion模型结构

详细描述一下stable Diffusion的推理过程 其实很简单 prompt先经过textencoder tokenizer&#xff0c;embedding 随机生成噪声图片 通过vae encode压缩成潜空间大小 unet with cross attn 去噪 并融合文本信息 # 上面两个信息如何混合 cross-attention sd模型中各种不同的采样器…...

Milvus(16):索引解释

索引是建立在数据之上的附加结构。其内部结构取决于所使用的近似近邻搜索算法。索引可以加快搜索速度&#xff0c;但在搜索过程中会产生额外的预处理时间、空间和 RAM。此外&#xff0c;使用索引通常会降低召回率&#xff08;虽然影响可以忽略不计&#xff0c;但仍然很重要&…...

数字化转型-4A架构之应用架构

系列文章 数字化转型-4A架构&#xff08;业务架构、应用架构、数据架构、技术架构&#xff09;数字化转型-4A架构之业务架构 前言 应用架构AA&#xff08;Application Architecture&#xff09;是规划支撑业务的核心系统与功能模块&#xff0c;实现端到端协同。 一、什么是应…...

中间件-RocketMQ

RocketMQ 基本架构消息模型消费者消费消息模式顺序消息机制延迟消息批量消息事务消息消息重试最佳实践 基本架构 nameServer: 维护broker列表信息&#xff0c;客户端连接时只需要连接nameServer。可配置成集群。 broker&#xff1a;broker分为master和slave&#xff0c;master负…...

AI开发playwright tool提示词

[TASK] 生成一个isModuleElementObject function&#xff0c;若element的qa-test class在对象moduleObj {"qa-test-mycourses-course": "qa-test-mycourses-course-title", "qa-test-discussion-module": "qa-test-discussion-description&…...

《Origin画百图》之带显著性标记的多因子分组柱状图

带显著性标记的多因子分组柱状图 需要数据&#xff1a; 组1&#xff08;大类&#xff09; 组2&#xff08;小类&#xff09; Y数据 Y误差 选中Y数据和Y误差两列数据&#xff0c; 点击绘图--分组图--多因子分组柱状图 数据列就是上一步选择的Y和Y误差&#xff0c; 点击子组…...

邮件发送频率如何设置?尊重文化差异是关键!

一、不同文化背景&#xff0c;邮件频率大不同 1.工作习惯不一样 一些西方国家&#xff0c;美国和欧洲工作时间和个人时间分得很清楚。工作日的上午 9 点到下午 5 点&#xff0c;这期间发邮件&#xff0c;收件人大概率会看也会回。但是在深夜或者周末发邮件容易让收件人觉得你…...

Python 识别图片上标点位置

Python识别图片上标点位置 要识别图片上的标点位置&#xff0c;可以使用Python中的OpenCV库。以下是几种常见的方法&#xff1a; 方法一&#xff1a;使用颜色阈值识别 import cv2 import numpy as np# 读取图片 image cv2.imread(image.jpg)# 转换为HSV颜色空间 hsv cv2.c…...

JDK Version Manager (JVMS)

以下是使用 JDK Version Manager (JVMS) 工具在Windows系统中安装JDK的详细步骤及注意事项&#xff0c;结合多篇搜索结果整理而成&#xff1a; --- 一、安装前准备 1. 下载JVMS - 访问 [GitHub Releases页面](https://github.com/ystyle/jvms/releases) 或镜像地址&#x…...

办公学习 效率提升 超级PDF处理软件 转换批量 本地处理

各位办公小能手们&#xff01;我跟你们说啊&#xff0c;有个软件叫超级PDF&#xff0c;那可真是PDF文件处理界的全能选手&#xff0c;专门解决咱们办公、学习时文档管理的各种难题。接下来我给大家好好唠唠它的厉害之处。 先说说它的核心功能。第一是格式转换&#xff0c;这软件…...

阿里云服务器-centos部署定时同步数据库数据-dbswitch

前言&#xff1a; 本文章介绍通过dbswitch工具实现2个mysql数据库之间实现自动同步数据。 应用场景&#xff1a;公司要求实现正式环境数据库数据自动冷备 dbswitch依赖环境&#xff1a;git ,maven,jdk 方式一&#xff1a; 不需要在服务器中安装git和maven&#xff0c;直接用…...

C++函数栈帧详解

函数栈帧的创建和销毁 在不同的编译器下&#xff0c;函数调用过程中栈帧的创建是略有差异的&#xff0c;具体取决于编译器的实现&#xff01; 且需要注意的是&#xff0c;越高级的编译器越不容易观察到函数栈帧的内部的实现&#xff1b; 关于函数栈帧的维护这里我们要重点介…...

Wireshark抓账号密码

训练内容&#xff1a; 1. 安装Ethereal或者Wireshark&#xff0c;熟悉网络嗅探器的使用方法&#xff1b; 2. 实现浏览器与IIS服务器的ssl安全访问&#xff1b; 3. 利用网络嗅探器截获浏览器访问IIS服务器之间数据包&#xff0c;包括有ssl安全连接&#xff08;https方式&am…...

【hot100】bug指南记录1

之前学了一阵C&#xff0c;还是更熟悉C的语法呀&#xff0c;转Java还有点不适应........ 这个系列纯纯记录自己刷题犯的愚蠢的错误......hhhh&#xff0c;我是人&#xff0c;one 愚蠢的码人...... 巩固巩固基础好吗&#xff1f;&#xff01;编程菜鸟.......hhh&#xff0c;又…...