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

Linux SID 开发指南

Linux SID 开发指南

1 前言

1.1 编写目的

介绍Linux 内核中基于Sunxi 硬件平台的SID 模块驱动的详细设计,为软件编码和维护提供基
础。

1.2 适用范围

内核版本Linux-5.4, Linux-4.9 的平台。

1.3 相关人员

SID 驱动、Efuse 驱动、Sysinfo 驱动的维护、应用开发人员等。

1.4 术语、定义、缩略语

image-20221219105007286

2 模块描述

2.1 模块功能

SID 提供的功能可以分为四大部分:ChipID、SoC Version、Efuse 功能、一些状态位。

2.1.1 Chip ID 功能

对于全志的SoC 来说,ChipID 用于该SoC 的唯一标识,如A83 的ChipID 标识其在所有A83 中的唯一(目前仅保证同一型号SoC 中的ChipID 唯一)。ChipID 由4 个word(16 个byte)组成,共128bit,通常放在Efuse(见2.1.3 节)的起始4 个word。具体ChipID 的bit 含义,请参考生产制造部为每颗SoC 定义的《ChipID 烧码规则》。

2.1.2 SoC Version 功能

严格讲SoC Version 包含两部分信息:
1.Bonding ID,表示不同封装。

  1. Version,表示改版编号。

说明:这两个信息所在的寄存器不一定都在SID 模块内部,且各平台位置不一,但软件上为了统一管理,都归属为SID 模块。

BSP 会返回这两个信息的组合值,由应用去判断和做出相应的处理。

2.1.3 Efuse 功能

对软件来说,Efuse 中提供了一个可编程的永久存储空间,特点是每一位只能写一次(从0到1)。
Efuse 接口方式,Efuse 容量大于512bit 采用SRAM 方式。带有SRAM 的硬件结构示意图如下:

image-20221219105300040

2.1.4 一些状态位

Secure Enable标明当前系统的Security 属性是否打开,即是否运行了SecureBoot 和SecureOS。
芯片SecureEnable 状态位保存在SID 模块的0xa0 寄存器。

2.2 模块位置

SID 是一个比较独立的模块,在Linux 内核中没有依赖其他子系统,在Sunxi 平台默认是ko 方式,存放在drivers/soc/sunxi 目录中。
SID 为其他模块提供API 的调用方式。关系如下图:

image-20221219105416344

1)TV、Thermal、GMAC 的校准参数保存在SID 中;
2)Nand、SMP、VE 需要读取SoC Version;
3)CE 和HDMI 会用到SID 中的一些Key;
4)Sysinfo 比较特殊,为了方便用户空间获取、调试SID 信息,专门设计的一个字符型设
备驱动。

2.3 模块device tree 配置说明(适用Linux-5.4)

SID 模块在Device tree 中通常会用到两个模块的配置信息:sunxi-sid 以sun50iw10p1为例,需要在sun50iw10p1.dtsi 中添加节点:

sid@3006000 {
compatible = "allwinner,sun50iw10p1-sid", "allwinner,sunxi-sid";
reg = <0x0 0x03006000 0 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
/* some guys has nothing to do with nvmem */
secure_status {
reg = <0x0 0>;
offset = <0xa0>;
size = <0x4>;
};
chipid {
reg = <0x0 0>;
offset = <0x200>;
size = <0x10>;
};
rotpk {
reg = <0x0 0>;
offset = <0x270>;
size = <0x20>;
};
};

在sid 下增加子节点secure_status, chipid, rotpk。就可以用key_info 来访问。

console:/ # echo chipid > /sys/class/sunxi_info/key_info ; cat /sys/class/sunxi_info/
key_info
console:/ # 00000400

2.4 模块源码结构

SID 驱动的源代码目录下:

linux-4.9,linux-5.4
./drivers/soc/sunxi/
└── sunxi-sid.c // 实现了SID对外的所有API接口

对外提供的接口头文件:./include/linux/sunxi-sid.h

2.5 内核配置

此配置项一般默认开,不需要重新配置
在longan 环境中在根目录执行./build.sh menconfig进入配置主界面,配置路径如下:

System Type
└─>ARM system type
└─>Allwinner Ltd. SUNXI family
版

配置界面图示:

image-20221219105647967

SID 驱动本身没有注册为单独的模块,需要通过注册sysinfo 字符驱动(实现代码见drivers/char/sunxi-sysinfo/)来提供sysfs 节点。
在longan 环境中在根目录执行./build.sh menconfig进入配置主界面,配置路径如下

Device Drivers
└─>Character devices
└─>sunxi system info driver

配置界面图示:

image-20221219105712117

3 模块设计

3.1 结构框图

SID 驱动内部的功能划分如下图所示:

image-20221219105727865

总体上,SID 驱动内部可以分为两大部分:
1.SID Register RW,封装了对寄存器按位读取的接口,以及获取指定compatible 的模块基地址等。
2.SID Api,以API 的方式提供一些功能接口:获取Key、获取SoC Version、获取SecureEnable、获取ChipID 等。

3.2 关键数据定义

3.2.1 常量及宏定义

3.2.1.1 key 的名称定义

在获取Key 的时候,调用者需要知道Key 的名称,以此作为索引的依据。Key 名称详见sunxisid.h:

1 #define EFUSE_CHIPID_NAME "chipid"
2 #define EFUSE_BROM_CONF_NAME "brom_conf"
3 #define EFUSE_BROM_TRY_NAME "brom_try"
4 #define EFUSE_THM_SENSOR_NAME "thermal_sensor"
5 #define EFUSE_FT_ZONE_NAME "ft_zone"
6 #define EFUSE_TV_OUT_NAME "tvout"
7 #define EFUSE_OEM_NAME "oem"
9 #define EFUSE_WR_PROTECT_NAME "write_protect"
10 #define EFUSE_RD_PROTECT_NAME "read_protect"
11 #define EFUSE_IN_NAME "in"
12 #define EFUSE_ID_NAME "id"
13 #define EFUSE_ROTPK_NAME "rotpk"
14 #define EFUSE_SSK_NAME "ssk"
15 #define EFUSE_RSSK_NAME "rssk"
16 #define EFUSE_HDCP_HASH_NAME "hdcp_hash"
17 #define EFUSE_HDCP_PKF_NAME "hdcp_pkf"
18 #define EFUSE_HDCP_DUK_NAME "hdcp_duk"
19 #define EFUSE_EK_HASH_NAME "ek_hash"
20 #define EFUSE_SN_NAME "sn"
21 #define EFUSE_NV1_NAME "nv1"
22 #define EFUSE_NV2_NAME "nv2"
23 #define EFUSE_BACKUP_KEY_NAME "backup_key"
24 #define EFUSE_RSAKEY_HASH_NAME "rsakey_hash"
25 #define EFUSE_RENEW_NAME "renewability"
26 #define EFUSE_OPT_ID_NAME "operator_id"
27 #define EFUSE_LIFE_CYCLE_NAME "life_cycle"
28 #define EFUSE_JTAG_SECU_NAME "jtag_security"
29 #define EFUSE_JTAG_ATTR_NAME "jtag_attr"
30 #define EFUSE_CHIP_CONF_NAME "chip_config"
31 #define EFUSE_RESERVED_NAME "reserved"
32 #define EFUSE_RESERVED2_NAME "reserved2"
33 /* For KeyLadder */
34 #define EFUSE_KL_SCK0_NAME "keyladder_sck0"
35 #define EFUSE_KL_KEY0_NAME "keyladder_master_key0"
36 #define EFUSE_KL_SCK1_NAME "keyladder_sck1"
37 #define EFUSE_KL_KEY1_NAME "keyladder_master_key1"

sunxi-sid.h 不是所有key 都能访问,一般可以访问的已经在dts 定义。

3.2.2 关键数据结构

3.2.2.1 soc_ver_map

用于管理多个SoC 的Version 信息,方便用查表的方式实现SoC Version API。其中有两个分量:id,即BondingID;rev[],用于保存BondingID 和Version 的各种组合值。定义在sunxi-sid.c 中:

#define SUNXI_VER_MAX_NUM 8
struct soc_ver_map {
u32 id;
u32 rev[SUNXI_VER_MAX_NUM];
};

对于一个SoC 定义一个soc_ver_map 结构数组,使用id 和不同Version 在rev[] 中查找对应的组合值。

3.2.2.2 soc_ver_reg

SoC Version、BondingID、SecureEnable 的存储位置因SoC 而异,所以定义了一个结构来记录这类信息的位置,包括属于那个模块(基地址)、偏移、掩码、位移等。定义见sunxisid.c:

#define SUNXI_SOC_ID_INDEX 1
#define SUNXI_SECURITY_ENABLE_INDEX 2
struct soc_ver_reg {
s8 compatile[48];
u32 offset;
u32 mask;
u32 shift;
};

每个SoC 会定义一个soc_ver_reg 数组,目前各元素的定义如下:
0 - SoC Version 信息在寄存器中的位置。
1 - BondingID 信息在寄存器中的位置。
2 - SecureEnable 信息在寄存器中的位置。

3.2.3 全局变量

定义几个static 全局变量,用于保存解析后的ChipID、SoC_Ver 等信息:

static unsigned int sunxi_soc_chipid[4];
static unsigned int sunxi_serial[4];
static int sunxi_soc_secure;
static unsigned int sunxi_soc_bin;
static unsigned int sunxi_soc_ver;

3.3 模块流程设计

3.3.1 SoC 信息读取流程

本节中,这里把SoC Ver、ChipID、SecureEnable 信息统称为“SoC 信息”,因为他们的读取过程非常相似。都是遵循以下流程:

image-20221219110111514

3.3.2 Efuse Key 读取流程

在读取Efuse 中Key 的时候,需要判断是否存在、以及访问权限,过程有点复杂,用以下流程图进行简单说明。

image-20221219110133623

4 接口设计

4.1 接口函数

4.1.1 s32 sunxi_get_platform(s8 *buf, s32 size)

• 作用:获取SoC 平台的名称,实际上是一个BSP 研发代号,如sun8iw11。
• 参数:
• buf: 用于保存平台名称的缓冲区
• size:buf 的大小
• 返回:
• 返回buf 中平台名称的实际拷贝长度(如果size 小于名称长度,返回size)。

4.1.2 int sunxi_get_soc_chipid(u8 *chipid)

• 作用:获取SoC 的ChipID(从Efuse 中读到的原始内容,包括数据内容和顺序)。
• 参数:
• chipid:用于保存ChipID 的缓冲区
• 返回:
• 会返回0,无实际意义

4.1.3 int sunxi_get_serial(u8 *serial)

• 作用:获取SoC 的序列号(由ChipID 加工而来,格式定义见《chipid 接口的实现方案》。
• 参数:
• serial:用于保存序列号的缓冲区
• 返回:
• 会返回0,无实际意义

4.1.4 sunxi_get_soc_chipid_str(char *serial)

• 作用:获取SoC 的ChipID 的第一个字节,要求转换为字符串格式。
• 参数:
• serial:用于打印ChipID 第一个字节的缓冲区
• 返回:
• 只会返回8(4 个字节的十六进制打印长度),无实际意义

4.1.5 int sunxi_get_soc_ft_zone_str(char *serial)

• 作用:获取FZ ZONE 的最后一个字节,要求转换为字符串格式。
• 参数:
• serial:用于打印ChipID 第一个字节的缓冲区
• 返回:
• 只会返回8(4 个字节的十六进制打印长度),无实际意义

4.1.6 int sunxi_get_soc_rotpk_status_str(char *status)

• 作用:获取rotpk 的状态,是否烧码
• 参数:
• status:用于记录是否烧码的缓冲区;0,未烧;1,已烧
• 返回:
• %d 的长度,无实际意义

4.1.7 int sunxi_soc_is_secure(void)

• 作用:获取整个系统的Secure 状态,即安全系统是否启用。
• 参数:
• 无
• 返回:
• 0,未启用安全系统;1,启用

4.1.8 unsigned int sunxi_get_soc_bin(void)

• 作用:用于芯片分bin,部分SoC 平台才支持。
• 参数:
• 无
• 返回:
• 0: fail
• 1: normal
• 2: faster
• 3: fastest

4.1.9 unsigned int sunxi_get_soc_ver(void)

• 作用:获取SoC 的版本信息。
• 参数:
• 无
• 返回:
• 返回一个十六进制的编号,需要调用者去判断版本号然后做出相应的处理。详情参看dts,
sid 节点。

4.1.10 s32 sunxi_efuse_readn(void key_name, void buf, u32

n)
• 作用:读取Efuse 中的一个key 信息。
• 参数:
• key_name - Key 的名称,定义详见sunxi-sid.h
• buf - 用于保存Key 值的缓冲区
• size - buf 的大小
• 返回:
• 0: success
• other: fail

4.2 内部函数

4.2.1 static s32 sid_get_base(struct device_node **pnode,

void __iomem **base, s8 *compatible, u32 sec)
• 作用:从DTS 中获取指定模块的寄存器基地址。
• 参数:
• pnode - 用于保存获取到的模块node 信息
• base - 用于保存获取到的寄存器基地址
• compatible - 模块名称,用于匹配DTS 中的模块
• 返回:
• 0: success
• other: fail

4.2.2 static void sid_put_base(struct device_node *pnode,

void __iomem *base, u32 sec)
• 作用:释放一个模块的基地址。
• 参数:
• pnode - 保存模块node 信息
• base - 该模块的寄存器基地址
• 返回:
• 无

4.2.3 static u32 sid_rd_bits(s8 *name, u32 offset, u32 shift,

u32 mask, u32 sec)
• 作用:从一个模块的寄存器中,读取指定位置的bit 信息。
• 参数:
• name - 模块名称,用于匹配DTS 中的模块
• offset - 寄存器相当于基地址的偏移
• shift - 该bit 在寄存器中的位移
• mask - 该bit 的掩码值
• 返回:

• 0,fail
• other,获取到的实际bit 信息

5 可测试性

  1. /sys/class/sunxi_info/sys_info
    此节点文件可以打印出一些SoC 信息,包括版本信息、ChipID 等:
# cat /sys/class/sunxi_info/sys_infosunxi_platform : sun50iw10p1
sunxi_secure : secure
sunxi_chipid : 00000000000000000000000000000000
sunxi_chiptype : 00000400
sunxi_batchno : 0x1
  1. /sys/class/sunxi_info/key_info
    此节点用于获取指定名称的Key 信息。方法是先写入一个Key 名称,然后就可以读取到Key 的内容。执行效果如下:
# echo chipid > /sys/class/sunxi_info/key_info ; cat /sys/class/sunxi_info/key_info
0xf1c1b200: 0x00000400
0xf1c1b204: 0x00000000
0xf1c1b208: 0x00000000
0xf1c1b20c: 0x00000000

6 其他说明

当启用安全系统后,Non-Secure 空间将无法访问大部分的Efuse 信息,这个时候需要通过SMC 指令来读取这些Key 信息。此时不能再使用普通的寄存器读接口readl(),而是调用的SMC 接口:

目前,sunxi_smc_readl() 的实现在源代码sunxi-smc.c,该文件保存在drivers/char/sunxisysinfo。

int sunxi_smc_readl(phys_addr_t addr)

目前,sunxi_smc_readl() 的实现在源代码sunxi-smc.c,该文件保存在drivers/char/sunxisysinfo。

相关文章:

Linux SID 开发指南

Linux SID 开发指南 1 前言 1.1 编写目的 介绍Linux 内核中基于Sunxi 硬件平台的SID 模块驱动的详细设计&#xff0c;为软件编码和维护提供基 础。 1.2 适用范围 内核版本Linux-5.4, Linux-4.9 的平台。 1.3 相关人员 SID 驱动、Efuse 驱动、Sysinfo 驱动的维护、应用开…...

Matlab进阶绘图第2期—线型热图

线型热图由共享X轴的多条渐变直线组成&#xff0c;其颜色表示某一特征值。 与传统热图相比&#xff0c;线型热图适应于X轴数据远多于Y轴&#xff08;条数&#xff09;的情况&#xff0c;可以很好地对不同组数据间的分布情况进行比较&#xff0c;也因此可以在一些期刊中看到它的…...

【Redis中bigkey你了解吗?bigkey的危害?】

一.Redis中bigkey你了解吗&#xff1f;bigkey的危害&#xff1f; 如果面试官问到了这个问题&#xff0c;不必惊慌&#xff0c;接下来我们从什么是bigkey&#xff1f;bigkey划分的类型&#xff1f;bigkey危害之处&#xff1f; 二.什么是bigkey&#xff1f;会有什么影响&#xff…...

C++回顾(一)——从C到C++

前言 在学习了C语言的基础上&#xff0c;C到底和C有什么区别呢&#xff1f; 1.1 第一个C程序 #include <iostream>// 使用名为std的命名空间 using namespace std;int main() {// printf ("hello world\n");// cout 标准输出 往屏幕打印内容 相当于C语言的…...

CRF条件随机场 | 关键原理+面试知识点

😄 CRF之前跟人生导师:李航学习过,这里结合自己的理解,精简一波CRF,总结一下面试中高频出现的要点。个人觉得没网上说的那么复杂,我看网上很大部分都是一长篇先举个例子,然后再说原理。没必要原理其实不难,直接从原理下手更好理解。 文章目录 1、概率无向图(马尔可夫…...

秒懂算法 | 回归算法中的贝叶斯

在本文中,我们会用概率的观点来看待机器学习模型,用简单的例子帮助大家理解判别式模型和生成式模型的区别。通过思考曲线拟合的问题,发现习以为常的损失函数和正则化项背后有着深刻的意义 01、快速理解判别式模型和生成式模型 从概率的角度来理解数据有着两个不同的角度,假…...

用Netty实现物联网01:XML-RPC和JSON-RPC

最近十年,物联网和云计算、人工智能等技术一道,受到业内各方追捧,被炒得火热,甚至还诞生了AIoT这样的技术概念。和(移动)互联网不同,物联网针对的主要是一些资源有限的硬件设备,比如监控探头、烟雾感应器、温湿度感应器、车载OBD诊断器、智能电表、智能血压计等。这些硬…...

腾讯云服务器centos7安装python3.7+,解决ssl问题

使用requests模块访问百度&#xff0c;报错如下&#xff1a; requests.exceptions.SSLError: HTTPSConnectionPool(hostwww.baidu.com, port443): Max retries exceeded with url: / (Caused by SSLError("Cant connect to HTTPS URL because the SSL module is not avail…...

C++【模板STL简介】

文章目录C模板&&STL初阶一、泛型编程二、函数模板2.1.函数模板概念2.2.函数模板格式2.3.函数模板的实例化2.4.模板参数的匹配原则三、 类模板3.1.模板的定义格式3.2.类模板的实例化STL简介一、STL的概念、组成及缺陷二、STL的版本C模板&&STL初阶 一、泛型编程…...

该学会是自己找bug了(vs调试技巧)

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:介绍c语言初阶的最后一篇.有关调试的重要性. 金句分享…...

Redis大全(概念与下载安装)

目录 一、概念 1.非关系型数据库&#xff08;NoSQL&#xff09;的介绍 2.什么是redis 3.redis的作者 4.Redis的特点 5.redis的应用场景 6.高度概括知识 一、二 缓存穿透、缓存击穿、缓存雪崩的概念 &#xff08;一&#xff09;缓存穿透 &#xff08;二&#xff09;缓…...

指针的进阶【上篇】

文章目录&#x1f4c0;1.字符指针&#x1f4c0;2.指针数组&#x1f4c0;3.数组指针&#x1f4bf;3.1.数组指针的定义&#x1f4bf;3.2. &数组名VS数组名&#x1f4bf;3.3.数组指针的使用&#x1f4c0;1.字符指针 int main() {char ch w;char* pc &ch;// pc就是字符指…...

MATLAB | 如何用MATLAB绘制花里胡哨的山脊图

本期推送教大家如何绘制各种样式的山脊图&#xff0c;这里做了一个工具函数用来实现好看的山脊图的绘制&#xff0c;编写不易请多多点赞&#xff0c;大体绘制效果如下&#xff1a; 依旧工具函数放在文末。 教程部分 0 数据准备 数据为多个一维向量放在元胞数组中&#xff0c;…...

.Net与程序集

一个简单的C#程序回想一下我们第一个.net 程序 hello world&#xff0c;它具有那些步骤呢&#xff1f;打开visual studio创建一个C# console的项目build运行程序这时候就有一个命令行窗口弹出来&#xff0c;上面打印着hello world。我们打开文件夹的bin目录&#xff0c;会发现里…...

软考中级之数据库系统(重点)

涉及考点:数据库模式,ER模型,关系代数与元祖演算,规范化理论,并发控制,分布式数据库系统,数据仓库和数据挖掘 数据库模式 三级模式-二级映射 常考选择题 三级模式,两种映射的这种涉及属于层次架构体的设计,这种设计为我们在应用数据库的时候提供了很多便利,同时提高了整个体…...

界面控件DevExtreme的Data Grid组件——让业务信息管理更轻松!

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序&#xff0c;该套件附带功能齐…...

【架构师】零基础到精通——网关策略

博客昵称&#xff1a;架构师Cool 最喜欢的座右铭&#xff1a;一以贯之的努力&#xff0c;不得懈怠的人生。 作者简介&#xff1a;一名退役Coder&#xff0c;软件设计师/鸿蒙高级工程师认证&#xff0c;在备战高级架构师/系统分析师&#xff0c;欢迎关注小弟&#xff01; 博主小…...

【java 8】方法引用与构造器引用

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…...

SGI 空间配置器

前言 空间配置器是 STL 六大组件之一&#xff0c;它总是隐藏在容器的背后&#xff0c;默默工作&#xff0c;默默付出。本文为《STL 源码剖析》读书笔记&#xff0c;主要讨论 SGI 版本空间的配置和释放&#xff0c;对代码进行解读时会改变一些写法&#xff0c;使其更易于阅读。…...

2023年白酒行业研究报告

第一章 行业概况 白酒是中国传统的酿酒业之一&#xff0c;历史悠久&#xff0c;源远流长。白酒指以高粱等粮谷为主要原料&#xff0c;以大曲、小曲或麸曲及酒母等为糖化发酵剂&#xff0c;经蒸煮、糖化、发酵、蒸馏、陈酿、勾兑而制成的&#xff0c;酒精度(体积分数)在18%-68%…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...