工业AI原生企业的定义与价值
工业AI原生企业并非简单地将通用人工智能技术移植到工业场景,而是从底层架构开始就为工业领域深度定制的新型技术供应商。这类企业通常具备一个显著特点:他们的技术产品生来就为了解决工业场景中的具体问题,比如设备预测性维护、生产工艺优化或质量缺陷检测。与传统AI公司不同的是,工业AI原生企业更注重技术与工业知识的融合,而非单纯追求算法层面的创新。这种深度结合让它们在应对复杂工业环境时表现出更强的适应性。
然而,工业领域的特殊性也意味着这类企业面临更高门槛。产线数据往往存在噪声大、格式不统一的问题,且不同行业甚至不同工厂的需求差异显著。正因如此,工业AI原生企业需要既懂技术又懂工业的人才团队,能够深入生产一线理解业务逻辑。这种跨界能力成为其核心竞争力的重要组成部分,但也导致真正能跑通商业模式的企业并不多见。
核心能力与行业适配性
工业AI原生企业的核心能力体现在三个方面:技术架构的工业兼容性、行业知识的沉淀效率以及解决方案的可扩展性。首先,他们的技术平台通常支持多源异构数据接入,能够直接对接PLC、SCADA等工业系统,而无需经过复杂的数据清洗和转换。这种原生兼容性大幅降低了实施门槛,让企业能够快速启动项目而不必担心数据孤岛问题。
其次是行业知识的积累方式。优秀的工业AI原生企业会通过模块化、组件化的方式沉淀行业经验,例如将钢铁行业的工艺优化模型调整为化工行业可用的版本。这种知识复用机制不仅加速了项目交付,还降低了定制化开发成本。不过,这种能力需要长期积累,新兴企业往往难以在短期内构建完善的行业知识库。
最后是解决方案的灵活性。工业场景的需求变化频繁,今天可能关注能耗管理,明天可能转向产能提升。工业AI原生平台需要能够通过低代码甚至零代码方式快速调整模型和规则,避免每次需求变更都带来冗长的开发周期。这种敏捷性正是传统工业软件供应商难以匹敌的。
典型案例与实战分析
广域铭岛在工业AI原生领域展现出独特价值,其基于Geega平台打造的智能制造解决方案已在家电、汽车等行业落地。例如为某家电企业实施的质检优化项目,通过AI视觉技术替代传统人工检测,将漏检率降低至0.5%以下,同时提升了3倍检测效率。这种成果得益于其平台对工业协议的天然支持和多年积累的行业知识库。但值得注意的是,该平台更擅长离散制造领域,在流程工业中的实践案例相对有限。
对比来看,美国的C3.ai提供了另一种发展路径。其工业AI平台专注于预测性维护和能源优化,尤其在石油、电力等流程工业中积累了丰富经验。埃克森美孚就利用其系统实现了炼油设备的故障预测,将非计划停机时间减少了40%。不过,C3.ai的解决方案定价较高,且对本地化部署的支持较弱,这对预算有限或数据合规要求严格的中国企业可能形成障碍。
另一家值得关注的企业是德国的Siemens Advanta,其将工业知识和AI技术深度融合,在数字孪生领域表现突出。欧洲企业这种扎实的工业根基值得借鉴,但其系统复杂度较高,需要客户具备较强的技术团队配合实施。

如题。

之前试过手机网络抓包,可以下载,但是音频估计被加密过了播放不了。

也试过手机录屏再提取音频但是音质不理想。

看看大佬们有没有其他方案?不要外接硬件录制的。

引言

消息队列的存储架构是决定其可靠性、吞吐量、延迟性能的核心因素,直接影响业务场景适配能力。本文聚焦三款主流消息队列 ——Kafka(LinkedIn 开源,侧重高吞吐)、RocketMQ(阿里开源,金融级特性突出)、JMQ(京东开源,侧重高可用与灵活性),从存储模型、数据组织、索引设计等维度展开深度对比,为技术选型与架构优化提供参考。​

本文将从概念辨析出发,系统拆解主流存储模型与存储引擎的设计逻辑,对比 JMQ、Kafka、RocketMQ的技术选型差异与架构设计。​
一、Kafka存储架构
1.1 核心存储模型:分区日志流
在这里插入图片描述

Topic - 主题

Kafka学习了数据库里面的设计,在里面设计了topic(主题),这个东西类似于关系型数据库的表,此时我需要获取中国移动的数据,那就直接监听中国移动订阅的Topic即可。

Partition - 分区

Kafka还有一个概念叫Partition(分区),分区具体在服务器上面表现起初就是一个目录,一个主题下面有多个分区,这些分区会存储到不同的服务器上面,或者说,其实就是在不同的主机上建了不同的目录。这些分区主要的信息就存在了.log文件里面。跟数据库里面的分区差不多,是为了提高性能。

至于为什么提高了性能,很简单,多个分区多个线程,多个线程并行处理肯定会比单线程好得多。

Topic和partition像是HBASE里的table和region的概念,table只是一个逻辑上的概念,真正存储数据的是region,这些region会分布式地存储在各个服务器上面,对应于kafka,也是一样,Topic也是逻辑概念,而partition就是分布式存储单元。这个设计是保证了海量数据处理的基础。我们可以对比一下,如果HDFS没有block的设计,一个100T的文件也只能单独放在一个服务器上面,那就直接占满整个服务器了,引入block后,大文件可以分散存储在不同的服务器上。

注意:
1.分区会有单点故障问题,所以我们会为每个分区设置副本数
2.分区的编号是从0开始的

在这里插入图片描述




Kafka 以「主题(Topic)- 分区(Partition)」为核心组织数据,每个分区本质是一个 append-only 的日志流,消息按生产顺序追加存储,保证分区内消息有序性。​

优点:可以充分利用磁盘顺序读写高性能的特性。存储介质也可以选择廉价的SATA磁盘,这样可以获得更长的数据保留时间、更低的数据存储成本。
1.2 数据组织:分段日志文件
•每个分区拆分为多个 Segment 文件(默认 1GB),命名格式为「起始偏移量.log」(如 00000000000000000000.log)​,做这个限制目的是为了方便把.log加载到内存去操作
•配套两类索引文件:.index(偏移量→物理地址映射)、.timeindex(时间戳→偏移量映射)​​

在这里插入图片描述




这个9936472之类的数字,就是代表了这个日志段文件里包含的起始offset,也就说明这个分区里至少都写入了接近1000万条数据了。

Kafka broker有一个参数,log.segment.bytes,限定了每个日志段文件的大小,最大就是1GB,一个日志段文件满了,就自动开一个新的日志段文件来写入,避免单个文件过大,影响文件的读写性能,这个过程叫做log rolling,正在被写入的那个日志段文件,叫做active log segment。
1.3 消息读/写过程
在这里插入图片描述

写消息:
•Index文件写入,Index文件较小,可以直接用mmap进行内存映射,避免频繁的磁盘I/O操作,提高写入性能;由于Index文件是稀疏索引,只需要记录关键位置的偏移量,因此即使使用mmap,写入的开销也相对较低。
•Segment文件写入,Segment文件较大,可以采用普通的写操作(FileChannel.write),由于Segment文件是顺序写入的,并且Kafka会利用操作系统的PageCache(页缓存)机制,写入操作会先写入到内存中,然后由操作系统在后台异步刷新到磁盘,可以进一步提高写入的性能。

读消息:
•Index文件读取,通常使用mmap方式读取,由于Index文件较小,且是稀疏索引,缺页中断的可能性较小。
•Segment文件读取,通常使用sendfile系统调用来实现零拷贝读取和发送,减少数据在用户空间与内核空间之间的拷贝次数,提高数据传输的效率。
1.4 关键技术

Kafka 作为高性能的消息中间件,其超高吞吐量的核心秘诀之一就是深度依赖 PageCache + 顺序 I/O + mmap 内存映射的组合。

PageCache,中文名称为页高速缓冲存储器。它是将磁盘上的数据加载到内存中,当系统需要访问这些数据时,可以直接从内存中读取,而不必每次都去读取磁盘。这种方式显著减少了磁盘I/O操作,从而提高了系统性能。

mmap(Memory-mapped file)是操作系统提供的一种将磁盘文件与进程虚拟地址空间建立映射关系的核心技术,本质是让进程通过直接操作内存地址的方式读写文件,无需传统的 read/write 系统调用。核心价值在于零拷贝和内存式文件访问,尤其适合大文件、高吞吐、随机访问的场景。

将日志段(.log)文件映射到内存,生产者写入时直接写内存(内核异步刷盘),消费者读取时直接从内存读取,实现超高吞吐(Kafka 的 “顺序写 + mmap” 是其高性能核心);

在这里插入图片描述

零拷贝流程示意图

零拷贝过程:
1.用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态
2.DMA控制器,把数据从硬盘中拷贝到内核缓冲区。
3.CPU将读缓冲区中数据拷贝到socket缓冲区
4.DMA控制器,异步把数据从socket缓冲区拷贝到网卡,
5.上下文(切换2)从内核态切换回用户态,sendfile调用返回。
1.5 设计优势
•顺序写磁盘:Segment 文件仅追加写入,规避随机 IO,吞吐量极高(单分区可达 10 万 + TPS)​​
•索引轻量化:仅维护偏移量与时间戳索引,降低存储开销​
•副本同步:基于 ISR 机制,仅同步已提交消息,兼顾一致性与可用性
二、RocketMQ存储架构

Kafka的每个Partition都是一个完整的、顺序写入的文件,但当Partition数量增多时,从操作系统的角度看,这些写入操作会变得相对随机,这可能会影响写入性能。
2.1 核心存储模型:分离式设计

RocketMQ采用「CommitLog + ConsumeQueue + IndexFile」三层结构,彻底分离数据存储与索引查询:​
•CommitLog:全局单一日志文件(默认 1GB / 个,循环覆盖),存储所有主题的原始消息​​
•ConsumeQueue:按主题 - 队列维度拆分的索引文件,存储「消息物理地址 + 偏移量 + 长度」,供消费者快速查询​
•IndexFile:哈希索引文件,支持按消息 Key 查询

CommitLog:消息的原始日记本

CommitLog是RocketMQ存储消息的物理文件,所有消息都会按到达顺序写入这个文件。你可以把它想象成一本不断追加的日记本——每条消息都是按时间顺序记录的新日记。

// 消息存储的核心逻辑简化示例(非源码)
public void putMessage(Message message) {

 // 1. 将消息序列化为字节数组
 byte[] data = serialize(message);
 // 2. 计算消息物理偏移量
 long offset = commitLog.getMaxOffset();
 // 3. 将数据追加到CommitLog文件末尾
 commitLog.append(data);
 // 4. 返回消息的全局唯一物理偏移量
 return offset;

}

消息写入CommitLog时有三个关键特性:
1.顺序写入:所有消息按到达顺序追加到文件末尾,避免磁盘随机寻址
2.内存映射:通过MappedByteBuffer实现文件映射,减少数据拷贝次数
3.文件分割:单个CommitLog文件默认1GB,写满后创建新文件(文件名用起始偏移量命名)

举个例子,当生产者发送三条消息时,CommitLog文件可能长这样:

0000000000000000000(文件1,1GB)
2|--消息A(offset=0)
3|--消息B(offset=100)
4|--消息C(offset=200)
500000000001073741824(文件2,起始偏移量1073741824)

温馨提示:虽然CommitLog是顺序写,但读取时需要配合索引结构,否则遍历文件找消息就像大海捞针。

消费队列ConsumeQueue:消息的快速目录

如果每次消费都要扫描CommitLog,性能会惨不忍睹。于是RocketMQ设计了ConsumeQueue——它是基于Topic和Queue的二级索引文件。

每个ConsumeQueue条目包含三个关键信息(固定20字节):

1| CommitLog Offset (8字节) | Message Size (4字节) | Tag Hashcode (8字节) |

这相当于给CommitLog里的消息做了一个目录:

TopicA-Queue0的ConsumeQueue
2|--0(对应CommitLog偏移0的消息A)
3|--100(对应CommitLog偏移100的消息B)
4|--200(对应CommitLog偏移200的消息C)

当消费者拉取TopicA-Queue0的消息时:
1.先查ConsumeQueue获取消息的物理位置
2.根据CommitLog Offset直接定位到CommitLog文件
3.读取指定位置的消息内容

关键设计点:
•ConsumeQueue采用内存映射+异步刷盘,保证高性能
•单个文件存储30万条索引,约5.72MB(30万*20字节)
•通过hashCode快速过滤Tag,实现消息过滤

索引文件IndexFile:消息的全局字典

如果需要根据MessageID或Key查询消息,ConsumeQueue就不够用了。这时候就要用到IndexFile这个全局索引。

IndexFile的结构类似HashMap:
1.Slot槽位(500万个):存储相同hash值的Index条目链表头
2.Index条目(2000万条):包含Key的hash值、CommitLog偏移量、时间差等信息

当写入消息时:

// 索引构建过程简化示意
public void buildIndex(Message message) {

// 计算Key的hash值
int hash = hash(message.getKey());
// 定位到对应的Slot槽位
int slotPos = hash % slotNum;
// 在Index区域追加新条目
indexFile.addEntry(hash, message.getCommitLogOffset());

}

查询时通过两次查找快速定位:
1.根据Key的hash值找到Slot槽位
2.遍历Slot对应的链表,比对CommitLog中的实际Key值

性能优化必知:
•消息体积差异大时,CommitLog仍然保持顺序写,但ConsumeQueue可能出现「稀疏索引」(相邻索引指向的物理位置间隔大)
•生产环境中CommitLog建议放在单独SSD磁盘,ConsumeQueue和IndexFile可放普通磁盘
•遇到消息堆积时,优先检查消费者速度,而不是无脑扩容Broker存储

理解这些底层机制,下次遇到消息查询性能问题或者磁盘IO瓶颈时,就知道该从CommitLog的写入模式还是ConsumeQueue的索引结构入手排查了。
2.2 数据流转机制
•生产者写入 CommitLog,生成全局唯一偏移量(PHYOFFSET)​
•后台线程异步构建 ConsumeQueue 索引,同步消息元数据​
•消费者通过 ConsumeQueue 定位 CommitLog 中的消息,避免全量扫描

存储过程全景图

现在把各个模块串起来看消息的生命周期:
1.生产者发送消息到Broker
2.Broker将消息顺序写入CommitLog
3.异步线程同时构建ConsumeQueue和IndexFile
4.消费者通过ConsumeQueue快速定位消息
5.按需查询IndexFile实现消息回溯

整个过程就像图书馆的管理系统:
•CommitLog是藏书库(按入库时间摆放)
•ConsumeQueue是分类目录(按题材/出版社分类)
•IndexFile是检索电脑(支持按书名/作者查询)
2.4 设计优势
•读写分离:CommitLog 仅负责写入,ConsumeQueue 负责查询,提升并发性能​
•事务支持:通过 CommitLog 中的事务状态标记 + 回查机制,实现分布式事务消息​
•刷盘策略:支持「异步刷盘(高吞吐)」「同步刷盘(金融级可靠性)」动态切换
三、JMQ存储架构

JMQ的消息存储分别参考了Kafka和RocketMQ存储设计上优点,并根据京东内部的应用场景进行了改进和创新。
3.1 核心存储模型:分区日志 + 队列兼容

在这里插入图片描述

JMQ存储的基本单元是PartitionGroup。在同一个Broker上,每个PartitionGroup对应一组消息文件(Journal Files),顺序存放这个Topic的消息。

与Kafka类似,每个Topic包含若干Partition,每个Partition对应一组索引文件(Index Files),索引中存放消息在消息文件中的位置和消息长度。消息写入时,收到的消息按照对应的PartitionGroup写入依次追加写入消息文件中,然后异步创建索引并写入对应Partition的索引文件中。

以PartionGroup为基本存储单元的设计,在兼顾灵活性的同时,具有较好的性能,并且单个PartitionGroup可以支持更多的并发。
3.2 消息读/写过程

在这里插入图片描述

写消息:

JMQ的写操作使用DirectBuffer作为缓存,数据先写入DirectBuffer,再异步通过FileChannel写入到文件中。
•消息写入DirectBuffer后,默认写入该节点成功(数据的高可靠是通过Raft协议复制,用多个内存副本来保证),相对Kafka的写操作来看,JMQ响应写入请求的处理过程没有发生系统调用,在京东内部的大量单条同步发送的场景下开销更低、性能更优。
•同时也避免使用MappedByteBuffer(Mmap方式)产生Page Fault中断,OS在中断中将该页对应磁盘中的数据拷贝到内存中,在对文件进行追加写入的情况下,这一无法避免的过程是完全没有必要,反而增加了写入的耗时的问题。

读消息:

JMQ采用定长稠密索引设计,每个索引固定长度。
•定长设计的好处是,直接根据索引序号就可以计算出索引在文件中的位置:索引位置 = 索引序号 * 索引长度。这样,消息的查找过程就比较简单了,首先计算出索引所在的位置,直接读取索引,然后根据索引中记录的消息位置读取消息。
•在京东内部应用场景中,单条消息处理耗时高是比较常见的,微服务架构下用户一般会申请更多的消费节点,让每个消费节点单次拉取较小批量的消息进行处理,以提升消费并行度,这样消费拉取请求的次数会比较多,稠密索引的设计会更适用内部的应用场景。

JMQ消费读操作99%以上都能命中缓存(JMQ设计的堆外内存与文件映射的一种缓存机制),避免了Kafka可能遇到的Cache被污染,影响性能和吞吐的问题。同时直接读内存也规避了RocketMQ在读取消息存储的日志数据文件时容易产生较多的随机访问读取磁盘,影响性能的问题。(当没有命中缓存时,会默认降级为通过Mmap的方式读取消息)。
四、竞品对比分析


JMQ

Kafka

存储模型

以PartitionGroup为基本存储单元,支持高并发写入

以Partition为基本存储单元,支持灵活的数据复制和迁移

消息写入性能

- 单副本异步写入性能与 Kafka 相当 - 三副本异步写入性能优于 Kafka

- 单副本异步写入性能与 JMQ 相当 - 三副本异步写入性能略低于 JMQ

同步写入性能

- 同步写入性能稳定,几乎不受网络延迟影响

- 同步写入性能受网络延迟影响较大,稳定性略逊于 JMQ

多分区性能

- 多分区异步写入性能与 Kafka 相当 - 同步写入性能略低于 Kafka

- 多分区同步写入性能更稳定,适合高并发场景

副本机制

支持异步复制,副本间数据同步性能较好

支持异步和同步复制,副本机制成熟,适合复杂部署

跨机房部署

- 同步写入性能基本不受影响 - 异步写入性能下降

- 同步写入性能受网络延迟影响较大 - 异步写入性能下降

适用场景

- 对同步写入性能要求高 - 副本异步吞吐要求高 - 大规模微服务集群

- 复杂分区的高并发同步写入 - 大规模分布式系统 - 多语言生态支持丰富

在单副本场景下,JMQ与Kafka的单机写入性能均十分出色,均可达到网络带宽上限。

然而,在更贴近生产环境的三副本场景中,两者特性出现分化:

JMQ在三副本异步写入下的极限吞吐优势明显,且在跨机房部署时,其同步写入性能表现良好,几乎不受网络延迟影响;而Kafka则在多分区同步写入场景下展现出更稳定的性能,衰减小于JMQ。在大部分异步吞吐场景及不同消息体下的性能趋势上,两者表现相当。

综上所述,JMQ尤其适合对同步写入性能和副本异步吞吐有极高要求的场景,而Kafka在复杂分区的高并发同步写入方面适应性更广。

此前,龙智联合 Perforce 公司共同参加了 VPS 2025 虚拟制作大会。活动现场,Perforce 解决方案工程师 Kory Luo 带来《从片场到银幕:使用 Perforce 简化虚拟制片流程》的精彩演讲,深入探讨了虚拟制作技术在影视行业的应用现状与核心挑战,并重点阐述了 Perforce 版本控制系统如何作为关键解决方案,赋能创意团队。

演讲指出,虚拟制作虽能提升效率与创意自由度,但也带来了海量数据管理、全球协作与流程变革的难题。Perforce P4 通过其独占文件锁、增量传输、联邦架构及Streams工作流框架等独特功能,有效解决了大型二进制文件的版本冲突、数据同步缓慢与工作流碎片化等问题。演讲结合 DNEG 与 Halo Entertainment 等顶尖工作室的成功案例,展示了 Perforce P4 如何将项目启动时间从数天缩短至分钟级,并保障数据安全与团队协作的流畅性。此外,演讲还介绍了 P4 One、P4 DAM 等面向艺术家与创作者的免费工具,旨在降低版本控制门槛,让技术无缝服务于创意,共同推动虚拟制作行业的创新与发展。

以下为演讲实录,欢迎收藏阅读!


大家好,欢迎来到VPS 2025创新影像周。今天我们想要与大家探讨一个正在改变游戏和影视行业的关键话题,即我们今天所提到的虚拟制作。

我们知道,随着LED墙、实时渲染以及云协作的广泛普及,虚拟制作已不再是一个概念性话题,它已经走到了现实的主流当中。但与此同时,我们也会遇到以下一些问题:例如,随着项目复杂度的急剧提升,您将面临数百万级别的文件或GB级乃至TB级的数据,以及全球团队的部署。这些都让传统工作流程面临着巨大的挑战。

在开始分享之前,我们想引发大家思考几个问题:

  • 如果您能将项目的启动时间从两天提升到20分钟,这对您的团队意味着什么?
  • 如果您能将海量数据同步到本地的速度提升十倍以上,是否会改变您的制作流程效率?
  • 如果您的团队能够分布式协作,而无需担心文件冲突或资产损坏,这是否能让创意实现真正的自由?
  • 如果您的艺术家或美术师只需在自己熟悉和喜爱的引擎(如虚幻引擎)中工作,而无需学习新的软件或插件,这是否能让他们真正解放,全身心投入到创意之中?

我们现在提到的这些场景已不再是想象,它们在现实中切实存在,并且许多顶尖创意工作室已将其结合到虚拟制作开发的过程中。因此,今天我们想向大家展示,顶尖工作室是如何借助Perforce版本控制软件,在虚拟制作中实施并缩短制作流程,让创意更快落地,提升团队协作效率,不再受工具或地域壁垒的限制,同时保障数据安全,让每一份资产都能无忧传输。

1、行业概况与挑战

首先来快速了解一下行业概况。

Perforce起步于游戏行业,但迅速扩展至影视、半导体、汽车与制造等大规模行业。我们来看一些真实的行业数据:

  • 在游戏项目中,构建文件可能达到数百万,数据总量可达数百GB,数字资产内容资源更是庞大,达到TB级别。
  • 在影视行业,无论是故事片还是剧集,都会面临数十万文件,数据体量同样为TB级别。
  • 在半导体行业,数据体量更为庞大,达到70TB左右,每天需提交7000次,单个服务器一天需处理4500万个命令行。
  • 在汽车与制造业,3D激光扫描数据达到PB级别,同时要求高度安全的数据传输保障,且团队遍布全球。

这些真实的数据告诉我们,传统的版本控制方式和工作流程已不适合当今快速发展的行业需求。Perforce 正是为这种规模而生,无论您是从事3D激光扫描还是影视管线制作,Perforce 的基础架构都能保持您的工作高速高效运转。

在虚拟制作领域,一提到虚拟制片,大家首先会联想到LED墙,但我想说明,虚拟制作不只是一套LED解决方案,它是一整套覆盖从拍摄空间到资产管理方方面面的解决方案。其核心是打造一个沉浸式环境,支持多场景虚拟拍摄,让导演和艺术家在不同空间切换场景,从而节省调度和布景时间,实现资源复用。如果能达到跨服务器共享资源,就无需重复创建已有资产,可以快速在仓库中找到适用于当前虚拟拍摄的资源进行复用,从而提升团队制作效率。

那么,在虚拟制作领域,我们遇到了哪些挑战?

首先是人才短缺。它毕竟是一项新技术,专业人员在进行In-Camera VFX时,需要了解渲染知识、懂得LED硬件的限制与品质、掌握正确的调试方法,并具备过硬的3D艺术场景创作技术。

第二个挑战是对变革的抵触。有些工作室明明可以通过虚拟制作完成创新或前所未有的内容拍摄,但因为它是新技术,所以害怕改变,墨守成规,继续采用传统方式拍摄。

第三个挑战与前两个密切相关,即在开发新的工作流程和管线时需要做出改变。传统拍摄的核心是在真实场景或绿幕下进行,后期制作在拍摄之后完成。而虚拟制作则不同,在拍摄现场即可看到接近成片效果的背景,拍摄在LED棚内进行,是一个实时渲染的逼真场景。由于大部分画面在前期已确认,后期只需做一些微调。这两种制作方式导致了流程上的巨大改变,需要让VFX团队尽早参与到制作和拍摄中。

在这一挑战中,Perforce可以帮助团队构建高效统一的工作管理流程,确保拍摄顺畅,现场调整的灯光、镜头和构图都可以通过Perforce进行版本控制。其强大之处在于,它几乎能与虚拟制作管线中所有主流工具无缝连接,例如游戏引擎。P4与虚幻引擎的内置集成非常强大,在虚幻引擎中即可找到P4的内置插件,完成绝大部分版本控制操作,无需花费额外时间和精力学习新工具。此外,Maya、3D Max、Blender等DCC软件,以及CI/CD、Jira或飞书等工具,也都能与P4完美集成。因此,越来越多的工作室通过Perforce助力并融合采纳虚拟制作,利用这项技术更安全、高效、快速且省钱地创造出之前根本无法创作的内容。

2、Perforce 在虚拟制片中的应用

接下来,我们探讨P4如何助力创意团队高效运作,保持工作流畅。这要归功于我们几大独有且行业其他版本控制软件不具备的热点功能。

第一是使用独占文件锁来防止合并冲突。我们知道,大型二进制文件资产不支持两个版本合并。如果一个美术师更改文件后,另一美术师同时更改,他们将无法合并,导致其中一人的工作白费。许多工作室在没有采用Perforce时经常遇到此类头疼问题。我们通过独占锁功能,从机制上禁止此类事件发生,让每个人的工作状态透明化,团队成员都知道他人正在对哪个文件进行改动,如果该文件被独占锁定,其他人就无法签出、更改,从而从根源上阻止合并冲突的发生。

第二是增量传输,这是市面上几乎所有版本控制软件都不具备的功能,能显著减少文件同步和提交的时间。其原理是,P4的智能增量传输通过算法将文件切割成小部分,比对前一版本与当前版本间的增量变化,仅将变化部分通过网络传输给服务器。对于一个几GB或十几GB的文件,相比传输整个文件,仅传输增量可能只有几MB,大大减少了传输时间。

同时,我们提供代理和边缘服务器。如果您的团队遍布全球或国内不同城市,通过代理和边缘服务器,可以为远端队友提供极速访问,其速度相当于访问本地服务器。

我们来看一下,如何通过P4的联邦架构实现规模化。如果您的团队迅速壮大,需要与世界各地的团队协作,例如进行外包项目,那么代理和边缘服务器就是我们可扩展的核心,也是联邦架构的基础。这种架构通过统一而灵活的分布式连接,保持所有人同步,并能轻松扩展基础设施以应对不断增长的需求。代理和边缘服务器可以快速实现数据和资产的下载同步。此外,我们还有备用服务器,当遇到不可抗力灾难,如主机突然断电或硬盘损坏时,它不会影响团队的项目工作流程,因为备用机可以瞬时启动代替主机,为团队提供数据和服务。通过我们的联邦架构,我们可以赋能团队发挥最佳表现。

P4不仅是一个版本控制系统,它与Git有很大不同,它更像一个框架或系统,可以帮助团队有序工作。其中一个非常强大的功能是Stream,它能迅速扩展工作流结构,提供一个可复用的框架。当您为某个项目制定好一个Stream框架,如果它对您的工作流程和效率有很大提升,您可以轻易地复制此框架应用到下一个项目中。这就是为什么我们能将项目启动时间大幅减少的原因,您可以复用某个成功项目的架构。例如,我们之前介绍的DNEG团队,您可以在官网上看到他们使用的技术架构,如果对此不了解,完全可以复用他们的架构应用到您的工作团队中。我们还可以根据性能或成本需求提供高级存储控制,例如归档仓或借助S3云存储来降低储存和运维成本,优化工作流程。我们的版本控制软件还提供完整的日志审计,通过日志可以看到每个人在每个时间点做了什么操作,涉及哪些资产,一切都可追溯。当遇到问题时,可以非常快速地解决,了解整个服务器在特定时间点发生的事情。

上图是一个常见的Stream框架图,中间是主流,下面连接的是开发流。开发流顾名思义,是进行日常工作的项目,例如在虚拟制作或渲染时产生的资产和数据都在开发流中进行。当项目比较完整或稳定时,可以将其同步合并到主流中。我们还可以根据项目所需的不同功能特性,例如视频、音频或程序员代码合并,为他们定制所需的Stream,让他们专门使用。这样,他们就无需面对整个庞大的数百万文件,只需聚焦于自己需要的部分。在项目逐渐稳定时,我们可以创建开发流,它相当于发布时当前版本所有状态的永久快照。如果进行版本修复,也可以在开发流中进行。从图中可以直观看到,每一个功能项在Stream框架里都做了完整的隔离,互相不打扰各自的工作流程进度。

3、Perforce 如何为技术总监赋能

技术总监是虚拟制作管线的粘合剂,他们需要确保艺术家、开发人员和工程师协同工作,因此需要制定非常规范、专一的流程。我们来看Perforce如何为技术总监赋能,帮助他们进行虚拟制作。

这里有一个真实案例,来自Halo Entertainment。如果大家了解这家公司,会知道他们参与过《阿凡达》、《少年派的奇幻漂流》、《鸟人》等获奖影片的预视觉化制作。因为其项目不断扩大,遇到了严重瓶颈。许多工作室在扩张过程中也会遇到类似麻烦:初期选择Git,但当项目变得如此复杂后,Git无法满足庞大且复杂的工作流程。因此,他们会采用Perforce进行版本控制和管理。但如果同时使用Perforce和Git,会发现流程变得更加碎片化。经过思考,他们最终决定全线采用Perforce进行版本控制。

具体措施是采用一个集中式P4服务器,为每个项目创建独立仓库进行专项管理。这种模式优化了工作流程,减少了管理错误,因为每个项目组成员都在同一仓库中进行版本控制,无需跳转到不同仓库或项目寻找文件。这一整体方案带来的改变非常可观,它将团队从繁琐流程中解放出来,让团队和艺术家更专注于艺术创作。项目启动时间从两天缩短到20分钟,并提升了协作效率,减少了电影过场动画工作流程中的瓶颈。

上图展示了Halo Entertainment工作室如何通过Perforce Stream实现规模化。它配备了多仓库的集中式Perforce服务器,每个仓库相应创建新的Stream。如果需要做大量开发工作,就创建开发流。他们将插件和虚幻引擎中的实际资产做了分割,插件存储在一个仓库,主要资产存储在另一个仓库。这种结构带来的优势是:它非常灵活,可以快速启动项目,无需重新设计工作流,可以完全复用Halo或DNEG已认证的工作流程来部署新项目。同时,它还能达到一致性,因为团队可以保持在统一的分支策略下,在同一个仓库里工作,更易于管理。

既然Halo已通过Perforce实现了效率飞跃和工作流程化,那么如果您的团队也面临相同问题,接下来该怎么做?

在虚拟制作中,由于规模和项目复杂度不断提升,您会发现工作流程碎片化问题非常严重,不同的项目、分支、工具导致合作效率低下且经常出错。控制这些问题的最佳实践是采用单一、统一的工作流。因为统一的规范能让团队保持清晰透明,减少沟通成本。更重要的是,实践中我们发现,单一工作流能让我们及早发现问题,从而尽早解决,避免因流程不一致导致的性能瓶颈。

4、Perforce推荐方案Stream

接下来,我们介绍P4版本控制软件中一个非常关键的工具——Stream。它不仅能实现我们所说的所有目标,还能彻底改变您的版本管理方式。如果您不了解Stream,我们来简单拆解一下这个概念。

简单来说,Stream是一个分支,但其功能远超分支。其核心价值在于可以定制工作区视图,让用户轻松切换视图。正如我们之前提到的,团队中职能各不相同,有开发人员、美术师、2D/3D视图、音频等不同职能人员,他们关心的资产文件不同。如果给每个人整个仓库的文件,他们会非常困惑或处理缓慢。如果每天都要下载数百万GB级别的文件,即使软件再快,也无法减少同步时间。因此,我们需要为他们定制特定的工作视图。您可以根据角色轻松进行视图的共享和切换。Stream有一个框架和走向,上层的Stream更稳定,例如发布流,其中的资产和代码都是稳定成熟的。往下是项目的主要文件,然后是开发流,用于新功能或新资产的变更,相对不稳定。通过Stream框架,可以清楚地让工作人员知道,在特定Stream中工作的意义和背后价值。例如,做美术、做代码、做开发的人员,看到的工作视图视角都不同。通过工作区在不同Stream间的切换,可以得到面对的不同资产文件。此外,Stream还有很多强大功能,例如可以导入模块,借鉴其他仓库的文件应用到现有版本仓库中,实现组件化。

我们还有其他类型的Stream,包括稀疏流和虚拟流。虚拟流是一个虚拟的流环境,它映射在父流上看到的一部分,相当于把纸卷成筒,通过视角看到想要的文件。在项目启动阶段,最简单有效的方法是只用一个Stream完成整个项目。如果您是小型工作室,创建一个Stream,把所有人都放在其中工作就完全足够了。随着项目推进,如果需要在稳定性和灵活性间找到平衡,可以创建开发流,日常工作在其中完成。当项目稳定时,可以将开发流中的文件通过合并方式复制到主流中,用主流文件做测试或演示。这种隔离让测试和开发环境互不打扰,减少风险,保持团队高效合作。当版本通过审核后,我们会创建发布流,永久保存该时间节点下版本的所有信息。发布流不仅支持版本冻结,还能让后续的热修复和开发在其中并行,避免影响主干。这意味着您的团队在发布后也可以继续修复问题,而不会打乱整体节奏。更重要的是,您可以按需创建新的发布流,例如发布1.0版本后进行后续开发,更新到1.1、2.0、2.1等版本,随时在项目成熟时通过发布流打标签。后续追溯文件或资产内容时,可以随时查看该时间节点的文件状态。有时,如果您不想创建新分支,但又需要为不同职能人员设定定制化视图,可以使用虚拟流。虚拟流是一个虚拟环境,创建时不会产生真实源数据,只是一个视图角度。

最后一个亮点是我们即将发布的LimitView。我们知道不同视角的视图是Stream的关键信息。LimitView在2025.2版本中允许客户端在规范中指定同步时不需要的文件及路径,其功能与虚拟流有重合,但虚拟流需要管理员创建,而工作区如果由您自己管理,使用LimitView就无需管理员为您创建不同的虚拟流,您可以自己管理需求,将不需要的文件从视角中删除。

我们再介绍一种新的流类型——稀疏流。它是一个全新的轻量级方案,用于小规模微调场景。如果您的项目非常庞大,有数百万文件和数百万GB数据,创建新流时需要将现有流中所有文件及元数据原原本本复制一遍,非常耗时。如果您只想对其中某些特定文件进行微调,创建完整分支就不是一个明智的选择,这时可以使用稀疏流。在传统流中,项目所有文件都要复制一份。但在稀疏流中,创建时不会复制父流中的文件,只有对产生更改的文件才会去复制文件、产生元数据,大大减少了元数据产生及存储空间紧张的困扰。存储大量文件非常耗资源并提升运维成本,合理减少新资产的产生对团队运维至关重要。

5、Perforce如何为3D艺术家和创作者赋能
我们讨论了Stream和工作流优化,但虚拟制作不仅是技术问题,更关乎创作。如何让3D艺术家和创作者——虚拟制作的核心——愿意接纳一个版本控制软件?在现实生活中,提到版本控制软件大家都会觉得很头疼,是否需要学习很多新技术、适应新工具?Perforce为3D艺术家和创作者完美消除了这一障碍,让创意与技术真正融合。

我们介绍新产品P4 ONE。它与传统版本控制工具不同,传统工具是让艺术家适应工具,而P4 ONE是来适应艺术家。我们完美了解您在工作流程中遇到的瓶颈和操作,使用P4 ONE无需改变您现有的一切。P4 ONE是一款免费的版本控制客户端,它可以让您的团队每天使用自己已有的创意工具,与版本控制无缝连接,第一天就能轻松上手。当您熟悉P4 ONE后,如果想与团队协作,可以使用我们的P4服务器,五人及以下免费,您可以为团队搭建工作流程和场景,体验版本控制如何在虚拟创作过程中为团队增效。

P4 ONE可以让创作者轻松预览2D和3D文件的真实缩略图,通过可视化时间轴追踪创意进度,并且在离线状态下也能完整进行版本控制操作,无需WiFi。您在创作资产时无需命名为1.0、1.1、1.2,当版本变更繁多,想要追溯历史某个时间段时,通过时间轴和P4 ONE,几次点击即可恢复任意历史版本。

在虚拟制作中,挑战不仅是版本控制。如果项目涉及数十万、数百万数字资产,如何快速找到想要的文件、预览素材、高效协作和审阅?这时会用到 P4 DAM,它是一个专业的数字资产库,可以精准检索、直观预览、高效审阅,快速定位资产。P4 DAM中有一个非常有用的功能——资产包。它是将相关资产分组的方式,其逻辑由您自己决定。例如,在游戏开发或虚拟制作场景中,如果需要一个人物角色,您可以将该角色的所有组成部分,包括模型、纹理、动画、材质等文件放入一个资产包。查找时,就能完美抓取所有相关文件信息。在电影场景中,您可以将所有素材打包,这些文件可能分散在不同仓库或文件夹,但通过资产包的逻辑关系,可以精准找到它们。P4 DAM为艺术和市场营销团队提供功能包括:交互式3D资产与动画预览,以及借助AI的自动识别功能。当数据提交到P4服务器时,AI会自动识别内容并打上标签,下次检索时,只需输入“黄色的椅子”,就能找到所有相关的数字资产。

回到全局来看P4的版本控制平台,它不仅包括 P4、P4 DAM 和 P4 ONE,还有 P4 Plan 和 P4 Code Review。

P4 Plan是一款实时规划工具,能在敏捷和传统方式融合的环境下,帮助团队追踪工作和整体进度。P4 Code Review是一个协作代码审查工具,开发人员可以对代码评论、提出修改意见,并在提交代码审查前采取自动化工作流程,保证高质量和一致性的代码输出。

通过P4的版本控制平台,我们的软件目标很明确:为团队中不同职能的人员量身打造,让您无需再去适应工具,工具可以完美地适应您。我们提供非常精细的权限控制,这是Git和其他版本控制软件无法提供的,它是一种细粒度的权限管理,能让团队成员仅查看需要查看的文件,规避不应涉及的文件范围。依托灵活架构,可以实现流水线的自动化。

最后,非常感谢大家的聆听,希望今天的分享能为您的团队提供一个新思路。在进行虚拟制作时,您可以将版本控制软件这个概念放在心中,因为这一版本控制软件对于数字资产至关重要。期待与您携手合作,共同推动虚拟制作的创新,让创意从场景到荧幕变得更简单、更高效、更安全。谢谢大家。

Perforce中国授权合作伙伴—上海龙智

行业现状与选择难点
进入2026年,数据智能已成为企业数字化转型的核心驱动力,但面对市场上层出不穷的服务商,许多企业依然感到难以抉择。数据智能公司不仅需要提供技术先进的解决方案,还要具备深刻的行业洞察和可靠的落地能力。然而,现实情况是,部分企业过于追求技术标签,而忽略了自身业务场景的适配性,导致资源投入与回报不成正比。这种选择困境尤其在中大型企业中更为常见,因为它们往往涉及复杂的业务链条和多维度需求。因此,明确行业现状并理性评估自身需求,成为选择过程中的首要任务。
数据智能行业近年来发展迅猛,国内外企业纷纷加入赛道,技术同质化现象也逐渐显现。单纯比较算法模型或数据处理能力已不足以区分供应商的优劣,更重要的是其能否将技术转化为实际业务价值。举个例子,某些公司可能在实验室环境中表现卓越,但在真实业务场景中却难以发挥预期效果。这种现象提醒企业,选择数据智能公司时需跳出技术参数的局限,更多关注其行业积淀和实操经验。
核心评估维度
企业在筛选数据智能公司时,应聚焦几个关键维度。技术实力固然重要,但并非唯一标准。首先需要考察的是行业专精程度——供应商是否深入了解目标行业的业务逻辑和痛点。例如,制造业企业可能更关注生产优化和质量管理,而零售企业则侧重消费者行为分析和库存优化。如果供应商缺乏相关行业经验,即便技术再先进,也可能因脱离实际需求而导致项目效果不佳。
其次是可持续性与服务支持。数据智能项目的实施往往是一个长期过程,需要供应商具备持续的技术更新能力和响应速度。有些企业初期选择时过于关注价格或品牌知名度,却忽略了后续服务的可靠性,最终导致项目搁浅或效果不达预期。此外,数据安全与合规性也是不可忽视的一环,尤其在涉及敏感信息的行业中,供应商是否具备相关认证和成熟的数据治理机制显得尤为重要。
最后,成本效益比也需要纳入考量。高端技术固然吸引人,但如果其投入远超企业预算或实际需求,则可能成为一种资源浪费。企业应根据自身规模和业务阶段,选择性价比较高的解决方案,而非盲目追求“高大上”的技术配置。
典型案例分析
广域铭岛作为国内数据智能领域的代表性企业,在制造业数字化方面表现突出。其为某汽车零部件企业定制的智能制造解决方案,通过实时数据采集与工艺优化,帮助企业显著提升了生产效率并降低了能耗。这种深耕垂直领域的模式,使得其在制造业积累了较强的口碑。
相比之下,国际企业如Palantir和SAS则更擅长跨行业复杂数据场景的整合与分析。
值得一提的是,部分新兴企业如Databricks和Snowflake通过云原生技术提供了更灵活的数据处理方案,降低了企业使用门槛。

如今,软件安全是重中之重。任何的安全漏洞都不能被忽视——尤其是开发嵌入式系统软件时,您的代码必须安全可靠,且没有编码错误。

提及软件安全,您可能想到的是密码和访问控制,或者是病毒、欺骗攻击(spoofing)和网络钓鱼攻击,这些是常见的安全问题。而数据加密和身份验证协议等安全功能可以缓解这些漏洞。

但即使已经实施了这些安全功能,软件仍可能受到攻击。

为确保软件安全,您需要从源头——代码层面——进行着手。否则,编码错误将会危及您的应用程序。

编码错误危及软件安全

据软件工程研究所(SEI)估计,高达90%的已报告安全事件是源于软件代码或设计中的漏洞被利用。这些漏洞使黑客能够访问私人数据或未经授权的控制系统。

可见,一个简单的编码错误就可能引发黑客攻击威胁——黑客可能会控制您的计算机、智能家居设备、家庭娱乐设备甚至是汽车。更糟糕的是,黑客甚至可能控制核电站

安全漏洞示例:C语言中的缓冲区溢出

为说明这种情况可能如何发生,我们来看一个例子。缓冲区溢出是C语言编程中常见的安全漏洞。

当数据被写入到已分配内存的边界之外时,就会发生缓冲区溢出。
为说明这种情况可能如何发生,我们来看一个例子。缓冲区溢出是C语言编程中常见的安全漏洞。

延伸阅读:什么是缓冲区溢出?如何防止缓冲区溢出漏洞?

例如:

char buff[10];
buff[10] = 'a';

此处声明了一个10字节的数组(索引范围0到9)。但程序随后试图向数组边界外的一个字节写入字符。若程序后续使用了数组相邻的内存区域,则会导致意外行为。

这已经够糟糕了,而情况可能会进一步恶化——缓冲区溢出可能使黑客获得系统控制权。

缓冲区溢出如何招致黑客攻击?

黑客可以利用缓冲区溢出漏洞进行攻击,致使程序崩溃、数据损坏,或直接窃取信息。

程序运行时会使用一块称为“栈”的内存区域。当前执行函数作用域内的变量将存储在栈中。函数调用的地址也会被存储,以便返回语句能返回到正确的位置。

当函数返回到调用函数时,程序将从上次中断的地方继续执行。因此,如果栈中的返回地址被篡改为指向某些恶意的替代指令,那么,这些指令将在函数返回时被执行。

如果程序正在接收数据——且未设置检查机制来确保输入缓冲区不会溢出——那么就有可能设计一个包含恶意代码的输入或“有效负载”。这种恶意代码会溢出输入缓冲区,并将栈中的返回地址覆盖为恶意代码的地址。

预防安全漏洞至关重要

预防缓冲区溢出等安全漏洞至关重要。而实现这一目标的方法,就是确保在编码时就杜绝可被利用的漏洞。

毕竟,如果窗户敞开着,加装再坚固的门锁也毫无意义。因此,提高安全性的关键,就是确保代码安全。

确保C语言代码安全的四种方法

编写安全的代码至关重要。在C语言编程中,有四个关键信息来源可帮助您确保代码安全。

1. CWE

您可以从通用缺陷枚举(CWE)中识别安全弱点。

什么是CWE?

CWE是由社区开发的C语言常见软件安全弱点列表,由MITRE公司维护。该列表可用作弱点识别、缓解和预防的基线。

CWE软件安全弱点列表

CWE列表对弱点进行了优先级排序。其中的“Top 25”(前25)条是综合了二十多个不同机构的意见评选出来的。他们根据弱点出现的频率和重要性对其进行评估。CWE中列出的(C语言程序中的)许多弱点都与缓冲区溢出有关。

这份Top 25列表还附带了一组有效的“强效缓解措施”。这些措施可帮助开发者减少甚至彻底消除Top 25中的整类安全弱点,同时也有助于应对CWE列表中记录的其他800多个弱点。

CWE致力于从源头遏制漏洞,其实现方式是教育设计人员、程序员和测试人员如何在软件发布前就消除常见错误。

2. CERT C

您可以将CERT C编码标准应用于您的代码。

什么是CERT C?

CERT C编码标准由软件工程研究所(SEI)的CERT部门发布。SEI是卡内基梅隆大学运营的研发中心,它的资金主要来源于美国国防部和国土安全部。

CERT C安全规则

安全编码专家会持续在维基平台上完善CERT C指南。每项指南包括:

– 标题

– 描述

– 不合规代码示例

– 合规解决方案示例

该指南涵盖编码和实现错误,以及低级设计错误。其目标是消除不安全的编码实践和可能导致漏洞的未定义行为。

    CERT C将漏洞定义为:一组允许攻击者违反明确或隐含安全策略的条件。

缺陷可能较为轻微,也可能不会影响软件的性能或运行结果,但它仍可能被攻击者利用,从而导致重大的安全漏洞。

3. ISO/IEC TS 17961:2013 "C Secure"

您可以应用ISO/IEC TS 17961:2013 “C Secure” 编码规则。

什么是ISO/IEC TS 17961:2013?

ISO/IEC TS 17961:2013制定了一套编码规则,这些规则使静态代码分析工具能够诊断超出语言标准要求的不安全代码。

C Secure编码规则

ISO/IEC TS 179671:2013包含了C语言安全编码的规则,每条规则都包含示例。

C Secure旨在制定可以自动强制执行的安全编码规则,用于检测C语言编程中的安全缺陷。要被视作安全缺陷,软件漏洞必须能被恶意用户或攻击者的行为触发。

实施这些规则的分析工具必须能够有效发现安全编码错误,且不会产生过多的误报。

4. MISRA C

您也可以使用MISRA来确保C语言的安全编码。

什么是MISRA?

MISRA为安全相关系统的开发提供最佳实践指南。其C语言编码标准已被多个行业广泛采用。

MISRA C 安全规则

MISRA C:2012 修订版1于2016年发布。该版本为C语言编程提供了额外的安全指南,包括新的规则和指令,并附有合规和不合规的代码示例。

这些指南可用于预防导致安全问题和安全漏洞的编码错误。

为什么MISRA C安全规则是嵌入式系统的理想选择?

MISRA C安全规则是嵌入式系统的理想选择。这是因为MISRA C的安全性可与其它C语言安全编码标准相媲美。此外,MISRA C在嵌入式系统行业中深受信赖,更是汽车行业首选的编码标准。

MISRA C安全规则示例

MISRA C安全规则可防止编码错误和安全漏洞,例如缓冲区溢出。

以下是MISRA C安全规则的示例:

MISRA C 规则 18.1

“对指针操作数进行算术运算后得到的指针,其地址应指向与该指针操作数相同的数组内的元素。”

此规则与以下CERT C规则作用相同:

ARR30-C

“请勿创建或使用越界指针或数组下标。”

两者都与C语言中的多个CWE漏洞相关,其中之一是:

CWE-119:对内存缓冲区边界内的操作限制不当

“该软件在内存缓冲区上执行操作,但可能读取或写入超出缓冲区预期边界范围的内存位置。”

遵循MISRA C规则或CERT规则可确保代码安全,并规避CWE中的常见漏洞。这是因为写入越界指针(或指针操作数)可能导致缓冲区溢出,从而产生易受攻击的代码;而读取越界指针(或指针操作数)则可能意外泄露信息给黑客。

因此,通过确保遵循这些规则,将避免严重的编码错误。您可以使用静态代码分析工具(如Perforce QAC)来强制执行MISRA和CERT规则。

MISRA C与其他标准的比较

MISRA C编码标准也适用于软件安全性比功能安全性更受重视的环境。

事实上,MISRA针对MISRA C:2012标准发布了两个附录,以帮助开发者将MISRA规则映射到C Secure和CERT C标准。

  • MISRA C和C Secure比较

MISRA C:2012 – 附录2展示了每条MISRA规则如何映射到ISO/IEC TS 17961:2013中的C Secure规则。

 MISRA C对C Secure的覆盖:90%规则,10%指令。

  • MISRA C对C Secure的覆盖:90%规则,10%指令。*

C Secure中的每条规则都对应MISRA C中的一条规则或指令。任何完全支持MISRA C的静态代码分析工具(如Perforce QAC),也将符合C Secure标准。因此,您可以灵活互换使用这些标准以确保安全。

  • MISRA C和CERT C比较

MISRA C:2012 – 附录3展示了每条规则如何映射到CERT C规则。

MISRA C对CERT C的覆盖:60%规则,20%指令,15%超出范围,5%未覆盖。

CERT C是为C11设计的。MISRA C:2012是为C99设计的。

在CERT C规范中,有15条特定于C11的规则超出了MISRA C:2012的范围。而在(MISRA C:2012范围内的)CERT C规则中,只有四条未被覆盖。因此,MISRA C覆盖了CERT C中的大部分安全规则。

注:使用Perforce QAC可自动检测这四条规则的全部违规情况。

将MISRA安全规则应用于您的代码

MISRA编码标准为确保C语言代码的安全性提供了一套最佳实践准则。采用MISRA安全规则是保障软件整体安全性的明智之选。

如果您需要采用一种编码标准,以增强对软件安全性的信心,建议考虑MISRA C标准。该C语言编码规范内容全面,并已在安全与关键任务项目中被证明行之有效。

使用Perforce QAC编写安全代码

您可以借助Perforce QAC 自动执行MISRA规则(适用于C或C++语言),这将大幅减少手动代码审查所需的时间,从而释放开发资源,确保项目按时交付,同时提升软件质量。

Perforce QAC 主要通过以下机制帮助开发人员高效编写安全代码:

1. 精准定位违规代码,即时修复

  • 实时诊断:支持 MISRA C 和 CERT C 标准,能在 IDE 中直接以“气泡”形式标记违规代码,实现“边写边查”。
  • 增量分析:仅分析修改过的代码文件,无需等待全量编译,大幅提升修复效率。
  • 所见即所得:双击报错即可跳转至代码具体行(如死代码、非法指针转换),快速修正。

2. 风险分级,聚焦核心

  • 严重性过滤:允许开发者通过过滤器(Severity Filter)屏蔽次要警告,优先解决“除以零”、“空指针”等高危致命漏洞。
  • 复杂度监控:自动计算函数圈复杂度,帮助团队快速识别出难以维护、易藏漏洞的“高风险代码块”进行重构。

3. 闭环管理,审计无忧

  • 合规例外管理:针对无法修复的规则违规,提供规范的“抑制(Suppression)”与“偏差(Deviation)”审批流程,杜绝随意忽略报错。
  • 自动化报告:一键生成详细的合规性报表与趋势图,为项目安全交付和外部审计提供可追溯的证据。

Perforce中国授权合作伙伴——上海龙智

在全球数字化业务迅速发展的当下,企业普遍将大量资源投入到创建安全的在线门户、开发API接口以及构建云端服务当中,整体运行高度依赖加密技术和信任机制。然而,大部分企业未能正确认识其中潜藏的重大风险,即SSL/TLS证书过期。事实上,证书过期这一隐患并非空穴来风,全球范围内几乎每周都会因数字证书过期而引发一系列损失的运营事故。当保障数据传输安全的“数字护照”突然失效时,造成的负面影响远不止单一的技术问题,而是可能导致一系列动摇企业稳定发展的连锁反应。JoySSL市场部总监指出,SSL证书过期问题由于其“低发频率与高损失”的特点,已成为当今企业数字化运营中普遍存在的风险盲点,这也是为何主动管理证书生命周期已从运营建议,上升为确保业务持续性和维护品牌信誉的核心战略之一。

服务中断引发企业业务连续危机

SSL证书过期带来的首要风险,便是业务直接中断,这种影响既迅速又严重。当下的主流浏览器和操作系统对过期证书采取了严格的“不可接受”政策,用户访问被迫中断,意味着商业交易渠道与在线服务完全关闭。

更为隐秘而影响深远的问题来自后端服务,所有与数字证书关联的前端功能将因证书过期而出现系统性失效。用户可能遭遇无法登录、数据加载失败或交易操作受阻等问题。业务陷入停摆,导致收入减少、用户流失以及处理问题的额外成本增加。

证书过期有损品牌声誉与用户信任

线上服务的稳定性与专业程度,是品牌形象的重要展现。SSL证书过期会对企业形象造成直接伤害,使得企业专业信誉受损,深刻影响B端客户以及合作伙伴对企业的长期信任。

而信任的安全机制可能反向引发问题,过期警告传递公司不安全信号,造成信任缺失。为重新建立受损的信任,企业需要投入远超于证书维护的额外努力。

SSL失效丧失搜索引擎信任与青睐

搜索引擎对网站可用性与用户体验制定了严格的衡量标准,因证书失效导致网站长期无法正常访问,会被视为不良体验,进而对搜索结果的排名进行降序处理。在此期间,网站的自然流量损失难以避免。此外,用户因一次访问错误后,可能会降低对该网站的信任,从而减少后续访问的可能性。

证书自动化方案提供持续安全保障

面对证书过期引发的一系列负面效应,JoySSL技术负责人认为,建立全面化的证书资产监控机制,自动扫描并识别网络资产中所有被使用的SSL证书,统一纳入监控系统。通过全局视角掌握证书资产,消除因“影子证书”导致的管理盲点。智能预警与自动续期功能流水线,确保提醒信息及时传达。自动化续约与部署可从申请、验证、签发到部署自动完成全任务,无需人工操作,完全避免人为疏漏。

数字化安全是一种动态且持续的过程,专业的证书生命周期管理能力已成为评估企业IT治理成熟度及业务韧性的重要指标。通过投资这样的管理体系,可助力企业实现业务稳定在线、品牌可信度持续提升以及稳健发展。

不是那种特大博主,那种一般都有专业团队管理了。

那种不大不小的自媒体博主们是怎么整理 & 存储素材的呢?

简单估算,每个几分钟的短视频,反复录制各种机位,感觉每个短视频的原始素材可能都是以 TB 为单位的,大的惊人。

NAS 这种感觉也只是适合数据增量一般的普通家庭。

另外,博主们会长期存储原始素材吗?

如题,要支持 Magsafe 的,不容易发黄的,价格无所谓。但不喜欢官方壳,想找个平替,凯夫拉配色不好看,而且不防摔就不考虑了

可能是之前看过很多加湿器的负面新闻,一直对这个东西很排斥,认为它不够安全。
但最近经历了持续的鼻部及咽喉干痛,以及感冒后,决定入手一台。

目前看好了 树新风 G1 ( 1000 元) 和 米家加湿器 3 Pro (1400 元),大佬们有用过的吗,或者有其他更推荐的

访问链接: https://snapvee.com

SnapVee 由我 100% Vibe Coding 写的生产级 AI 工具,从 UI 设计、需求开发、测试、机器部署 -> 上线,总共代码行数约 4.3w 行,算上配置文件 5.7w 行。

3 天时间是怎么分配的

Day 1 ( 12h )

  • 产品定位 & MVP 功能清单
  • 落地页 + UI 主题定型
  • Auth / 数据库 Schema
  • 基础部署

Day 2 ( 14h )

  • 核心功能(下载 / 解析 / 队列)
  • 存储 & R2 / Redis 接入
  • Stripe 支付
  • SEO / i18n

Day 3 ( 10h )

  • BUG 修复 & 压测
  • 文案、价格、FAQ
  • 域名、合规、上线

模型选择

模型一定要用最好,最贵的模型,能省下很多事情!

Gemini3 Pro

Antigravity 刚出来的时候,就用了,免费额度很多。写一些 demo ,玩具是没有问题的,它在上下文理解和解决 BUG 能力上弱很多,而且还不是中文回复。

GLM4.7 模型

被朋友安利说 openCode 体验还不错。但实际体验过之后,你会发现一坨屎。比 Trea 稍微强上一点吧,执行任务时间长、流程长、会反复报错,反复执行。执行完之后的代码,无法一次运行,有各种 BUG 需要反复改。

Opus4.5

代码模型的神! Plan 模式和 Agent 模式都很舒服。运行速度快,理解能力强,任务规划强。最近又出了 Debug 模式。

能用最贵的代码模型,直接用!这里我用的 Opus4.5 ,成本如图。

UI 设计

我自己没有 UI 设计能力,但业界有很多设计模板网站和组件,这里我选择的是 framerreactbits

都有优秀的 UI 组件和 UI 模板,做出海网站,落地页面的整体架构都是类似的

  • Header (头部)

  • HeroSection (主视觉区)

  • FeatureIntroduction (功能介绍区)

  • PriceSection (价格区)

  • TestimonialsSection (用户评价)

  • FAQSection (答疑)

  • Footer (底部)

我的做法是确定网站的主题,这里选择的是黑紫主题。基于选择主题,再进行填充上面的内容,找到合适的组件。每个组件都可以自行风格话调教,你需要的动画,颜色,展示方式等。

得益于 opus 强大的记忆功能,我在后续的新增功能和 UI 改造,它都能记住网站是黑紫主题。也难怪 Tailwind 要裁员。

技术选型

  • Next.js 全栈型框架

  • UI 库 Shadcn

  • 数据库 Supabase

  • Redis Vercel

  • 邮箱注册 & 谷歌登录 auth.js

  • 邮件发送 resend

  • 存储服务 cloudflare r2

  • 机器 digitalocean

  • 前端部署 Vercel

  • 支付 Stripe

AI 时代下的模型物料训练对 TS 开发人员来说,非常友好!我个人认为 AI 模型能够达到前端资深甚至是专家级别的能力,只要你会使用。

纯 AI 实现一个视频编辑器,都没啥问题。

UI 库用的 Shadcn,不得不说 Shadcn 对 AI 来说简单快速,你要实现自己的一个组件库,很简单。

能用免费的,基本都是免费的,不免费的服务,也有试用额度,基本够用。

AI 模型对话

一句话:你得自己清楚你要实现什么功能,AI 模型才能跟你实现。

比如我这个产品要实现的功能有:

  • 注册登录
  • 落地页
  • 前端部署
  • 后端部署
  • 数据库建表
  • Redis 链接
  • SEO 优化
  • 其他等等

我个人认为,如果你对这些功能没有一个基本的认知。虽然 AI 能够完全帮你实现,但细节上就欠缺。举个例子,Google 登录,AI 帮你生成一份文档,你需要照着文档去操作,如果你不会,那你自然没法操作。

不过,这也让我惊叹于 Opus4.5 强大的编程能力,我让它实现一个 r2 存储服务。它居然可以自动帮我操作浏览器来实现

<video id="video" controls >
<source id="mov" src="https://oss.api-service.net.cn/1%E6%9C%8826%E6%97%A5-1.mov" type="video/mp4">
</video>

实现一个完整的功能,直接使用 Plan 模式,跟它对齐实现方案和要点。

这里我没有去追什么

  • .Claude 文件
  • Skills 文件夹
  • MCP 工具等

完完全全就是和它一起过 Plan 计划,对齐方案,然后 Build ,简简单单,它就能很好的理解,而且每次运行完的代码,是完全能够运行。而不是需要去修复 BUG 啥的。

所以,这里产生了大量的文档,都是跟它过 Plan 计划之后产生的。

我觉得好用的 AI 代码模型就是这样

AI 最容易出问题的 5 个点

  • OAuth / Google 登录(平台配置 ≠ 代码)

  • Stripe Webhook (时序 + 幂等)

  • SEO ( AI 不懂搜索引擎“潜规则”)

  • 边界状态(并发、异常、重试)

  • 成本估算( AI 不心疼钱)

虽然 AI 能写代码,能写文档配置,但不能替你承担线上事故,以及一些细节 AI 是不懂的。

总结:Vibe Coding 的前提,是你脑子里已经有架构。AI 时代下,对于程序员来说,最好是拥有架构的能力,变成一个 AI 架构师。

@playaround 上周这位朋友提到想提取小睡眠 APP 的音频,上周看了一下音频是加密的,基本上需要的数据都能拿到,因为上周没有设备,也没环境,今天装了大半天的环境,记录一下过程。

小睡眠音频有提取方案吗?: 小睡眠音频有提取方案吗?

注:破解软件属于违法行为,有偿服务可触犯刑法,本文仅为学习交流使用,文中涉及网址和核心解密的部分打码了。

过程

安卓 7.0 以上不再信任用户 CA 证书,导致新设备无法抓包,会提示网络错误等,部分 APP 配置了证书信任目录,即使低于安卓 7 仍然不可抓包,解决方案为把用户证书移动到系统证书目录(需 root),这里用的模拟器测试的。
image
反编译获取解密逻辑
通过网络请求获得 secret
此处的 secret 还不能直接用

image
通过加载 libbase.so 文件,调用 getkey 方法转换网络请求得到的 secret

image
抓包获取 secret

image
逆向 libbase.so 文件,获得 Java_com_psyone_brainmusic_utils_Base_GetKey 执行逻辑
image
返回的是 md5(secret+硬编码字符串)

image
验证 getkey 逻辑,完全正确

至此已获得解密所需的 secret 信息,key、iv 转换方法,对文件进行解密即可,后面不再赘述。

第二章 初识ESP32-P4

在本章中,我们将深入探索ESP32-P4这款备受瞩目的微控制器。我们将详细阐述其定义、核心资源、功能应用,以及如何选择适合您项目的ESP32-P4型号。通过本章的学习,您将全面了解ESP32-P4,为您的物联网项目选择合适的硬件平台奠定坚实基础。
本章分为如下几个小节:
2.1 ESP32-P4概述
2.2 ESP32-P4资源概述
2.3 ESP32-P4 命名规则
2.4 ESP32-P4 功能概述
2.5 ESP32-P4 启动流程

2.1 ESP32-P4概述

ESP32-P4是一款高性能MCU,支持超大片上内存,具有强大的图像和语音处理能力。该款MCU包含一个高性能(HP)系统和一个低功耗(LP)系统。其中HP系统由RISC-V双核处理器驱动,包含丰富的外设;LP系统由RISC-V单核处理器驱动,其外设针对低功耗应用进行了优化。下图为ESP32-P4芯片的功能框图。

图2.1.1 ESP32-P4功能框图
这里,笔者结合《ESP32-P4数据手册》中的“Product Overview”章节和上图的内容,简单归纳为5个部分。
1,架构和性能:ESP32-P4采用RISC-V 32位双核处理器(HP系统,400 MHz)和单核处理器(LP系统,40 MHz),具有高效的处理能力和性能。
2,存储:HP系统配备128 KB ROM和768 KB L2MEM,LP系统配备16 KB ROM和32 KB SRAM,支持8 KB的系统紧密耦合内存(TCM)和多个外部存储器接口。
3,外设:提供55个可编程GPIO和多个高级外设接口,包括JPEG解码器、视频编码器和多种数字接口与模拟接口,增强系统的灵活性和扩展性。
4,通信:同时支持多种通信协议,如USB、以太网、SPI、UART等,适用于物联网设备在智能家居和工业自动化等领域的广泛应用。
5,安全机制:具备安全启动、一次性写入安全性(eFuse OTP)和加密硬件加速器,确保数据和系统的安全性。
ESP32-P4是一款功能强大、性能丰富的物联网芯片,适用于各种物联网和音视频等应用场景。以上信息仅供参考,如需了解更多信息,请访问乐鑫公司官网查询相关资料。

2.2 ESP32-P4资源概述

ESP32-P4芯片为开发者提供了丰富的硬件资源和高灵活度的管脚功能,以适应多种物联网应用需求。本章节将介绍芯片的管脚布局以及各个IO管脚的功能,帮助开发者更好地理解如何高效利用这些资源。

2.2.1 管脚布局概览

下图为ESP32-P4管脚分布图。

图2.2.1.1 ESP32-P4管脚布局(俯视图)
上图中,ESP32-P4芯片总共有104个管脚,这些管脚可分为以下几类:
1,IO管脚:上图中的GPIO0~GPIO54,这些IO具有以下预设功能:
1)所有IO管脚均预设了HP IO MUX功能。
2)部分IO管脚预设了LP IO MUX功能。
3)部分IO管脚预设了模拟功能。
关于HP IO MUX、LP IO MUX和模拟功能的详细信息,将在后面的2.4.3小节中进行讲解。
2,专用数字管脚:仅可用于特定外设,如Flash、MIPI DSI、MIPI CSI等。这些管脚在上图中用橙色、红色、黄色和绿色框框标识。
3,特殊模拟管脚:专用于特殊模拟功能。上图78、79、99、100、103号管脚为特殊模拟管脚,这些特殊模拟管脚描述如下表所示。

图2.2.1.1 模拟管脚
上表展示了ESP32-P4芯片提供的一些特殊模拟管脚,用于特定的电源管理和时钟功能。其中,XTAL_N和XTAL_P需要连接一个40MHz晶振,以启动ESP32-P4芯片。CHIP_PU管脚用于芯片的使能控制,必须进行上拉才能启动芯片。EN_DCDC管脚用于控制同步降压DC-DC转换器。FB_DCDC管脚与内部参考电压进行比较,使控制器能够调整EN_DCDC管脚的占空比,以稳定输出电压。下图为DNESP32P4开发板中的同步降压DC-DC转换原理图。

图2.2.1.2 同步降压DC-DC转换
用户可以在其他平台上找到TLV62569 DC-DC电源芯片的数据手册。在手册的第9页中,有一个相关的转换公式,如下图所示。

图2.2.1.3 TLV62569 DC-DC电源芯片转换公式
在上图中,R1和R2分别对应原理图中的R9和R12。根据该公式计算,得出Vout为1.2V,从而为HP系统的内核提供所需电压。
4,电源管脚:为芯片和非电源管脚提供供电,如下表所示。

表2.2.1.2 电源管脚
通过控制VDDPST_1至VDDPST_6管脚,用户可以灵活调整各IO管脚的输出电压,以满足不同外设的电压需求。此外,VFB/VO1至VFB/VO4(图2.2.1.1中用黑色框框标识)管脚可以通过程序调节内部LDO的输出电压。通常情况下,我们将VFB/VO1至VFB/VO4连接到VDDPST_1至VDDPST_6的IO管理电源域,这样可以通过程序控制特定IO管脚的输出电压。为了让读者更好地理解这一功能,我们在DNESP32P4开发板上将VFB/VO3和连接至VDD_MIPI_DPHY以及将VFB/VO4和连接至VDDPST_1,这样便可以通过程序灵活控制MIPI和VDDPST_1电源域中IO的电压了。下图为可调LDO控制电源域原理图。

图2.2.1.4 通过VO3来控制MIPI电源域的IO
有些读者可能会有疑问?为什么需要这个功能呢?。其实很多器件不一定用到3.3V电压启动的,就比如我们正点原子的MIPI显示屏,驱动的IO电平必须是1.8V,所以我们可以通过可调LDO来控制这些不同电压驱动IO器件。

2.2.2 IO管脚功能说明

在上小节中,我们了解到ESP32-P4具有55个可编程IO管脚(GPIO0~GPIO54)。这些IO管脚具有三种预设功能,分别为全部IO管脚的IO MUX功能、部分IO管脚的LP IO MUX功能和部分IO管脚的模拟功能。如下表所示。

表2.2.2.1 部分外设管脚分配
从上表可知,ESP32-P4的IO MUX功能使得所有GPIO管脚能够灵活配置为多种数字信号接口,例如UART、I2S、I2C等,利用ESP32-P4的55个任意IO实现相关通信信号;与此同时,部分IO管脚的LP IO MUX功能专为低功耗应用设计,允许某些管脚在待机状态下保持活跃,以支持LP I2C和LP I2S等通信方式,从而有效节省能耗(如下图为LP系统管理的IO);此外,部分GPIO管脚具备模拟功能(如表中的ADC和TOUCH管脚,其他IO则不具备此功能),能够处理连续信号,直接与传感器和音频设备交互,拓展了ESP32-P4在多样化应用场景中的适用性。

图2.2.2.1 LP系统管理的IO
如果LP系统启动时,我们可以利用上图的IO管脚实现I2C、I2S等多种通信,因为这些信号可以灵活地映射到任意的IO管脚上。这种灵活性使得我们能够根据具体需求驱动相应的器件,从而更好地适应不同的应用场景和设计要求。
值得注意的是,某些外设必须使用特定的管脚实现,例如具有调试功能的JTAG、USB串口/JTAG、全速USB 2.0和EMAC等。如果在开发时未使用这些外设,我们可以利用IO MUX功能对特定通信接口进行映射。然而,这些映射可能会影响传输速率,因此笔者建议开发者首先采用ESP32-P4默认的复用功能IO设计原理图,然后再考虑其他IO映射功能,以确保系统性能的稳定性和可靠性。

2.3 ESP32-P4 命名规则

乐鑫P4系列包含两款芯片:ESP32-P4NRW16和ESP32-P4NRW32,它们之间的唯一差异在于PSRAM容量。以下是这两款芯片的命名规则图示。

图2.3.1 ESP32-P4 系列芯片命名规则
从上图可以看到, H/N表示FLASH温度(H:高温,N:常温);R表示内置PSRAM;W表示仅持1.8v 16-line PSRAM;x表示内置PSRAM大小(MB);。

2.4 ESP32-P4 功能概述

2.4.1 时钟树

ESP32-P4的时钟主要来源于振荡器(oscillator,OSC)、 RC振荡电路和PLL时钟生成电路。上述时钟源产生的时钟经时钟分频器或时钟选择器等时钟模块的处理,使得大部分功能模块可以根据不同功耗和性能需求来获取及选择对应频率的工作时钟。下图为ESP32-P4系统时钟结构。

图2.4.1.1 HP和LP系统时钟树
在上图中,十多路时钟源通过分频器或直接连接的方式供给各个外设。这样,各模块可根据功耗和性能需求,选择和获取相应的工作时钟频率。
接下来,笔者根据HP系统和LP系统的应用不同,划分为两个类型的时钟。
1,高速时钟
1)CPLL_CLK:内部400MHz时钟,CPU主频可由该时钟提供。
2)MPPL_CLK:内部500MHz时钟,PSRAM_CLK可由该时钟提供。
3)SPLL_CLK:内部480MHz时钟,FLASH_CLK/PSRAM_CLK可由该时钟提供。
2,慢速时钟
1)XTAL32K_CLK:外部32KHz石英晶振时钟。
2)RC_SLOW_CLK:内部慢速RC振荡器,频率可调,默认150KHz。
3)RC32K_CLK:内部32KHz RC振荡器。
4)XTAL_CLK:40MHz外部石英晶振时钟。
5)RC_FAST_CLK:内部快速RC振荡器,频率可调,默认20MHz。
6)PLL_LP_CLK:内部PLL时钟,默认为8MHz。
其中,高速时钟用于HP系统及其数字/模拟外设,而慢速时钟则用于LP系统以及某些低功耗模式下的外设。由此可见,我们可以将上图2.4.1.1划分为两个部分:上部分(红色区域)为HP系统所需的时钟,下部分(绿色区域)为LP系统所需的时钟。
前面我们已经了解到,ESP32-P4芯片集成了高性能(HP)系统和低功耗(LP)系统。其中,HP系统的主频最高可达400MHz,而LP系统的主频最高则为40MHz。那么,如何配置这两个系统以达到其最高主频呢?接下来,笔者将结合《ESP32-P4技术参考手册》,详细讲解这两个系统的主频配置方法。
1,HP系统时钟配置
由上图红色区域可知,CPU_CLK是HP系统的主频时钟,由XTAL_CLK、CPLL_CLK和RC_FAST_CLK这三个时钟源提供(LP_CLKRST_HP_CLK_CTRL_REG寄存器中的第0~1位(即LP_CLKRST_LP_CLK_SEL字段)来选择时钟源)。若要将HP系统的主频配置为400MHz,则必须选择CPLL_CLK作为时钟源,并将其频率设置为400MHz。此时,分频器(DIV)不进行分频(即1分频,意味着直接传递原频率),从而确保CPU_CLK的频率为400MHz。
MEM_CLK、SYS_CLK和APB_CLK时钟则是由CPU_CLK时钟经过分频得到的。另外,MPLL_CLK和SPLL_CLK也会经过分频器(DIV)进行分频,以产生不同频率的时钟信号。这些时钟信号被提供给HP系统的各个模块,各模块根据自身的功耗和性能需求来选择相应的时钟频率。下图是派生的HP时钟源。

图2.4.1.2 派生的HP时钟源
上图中,左边“Source Clock”为原始时钟源,右边“Derived Clock”为派生时钟源(由原始时钟源经过分频得到)。下图为HP系统外设时钟源选择。

图2.4.1.2 HP系统外设时钟源选择(部分截图)
关于ESP32-P4的HP系统外设时钟源选择,可以参考《ESP32-P4技术参考手册》中的453页8.2-4和8.2-5表格。
2,LP系统时钟配置
由上图绿色区域可知,在“active”模式下,LP_FAST_CLK是LP系统(低功耗系统)的主频时钟,它由XTAL_CLK、RC_FAST_CLK和PLL_LP_CLK这三个时钟源提供。我们可以通过操作LP_CLKRST_LP_CLK_CONF_REG寄存器中的第0~1位(即LP_CLKRST_LP_CLK_SEL字段)来选择时钟源。若要将LP系统的主频配置为40MHz,则必须选择XTAL_CLK作为时钟源,并将其频率设置为40MHz。
在‘Light-sleep’或‘Deep-sleep’模式下,一般选择LP_SLOW_CLK作为时钟源,该时钟由RC_SLOW_CLK、XTAL32K_CLK、RC32K_CLK和OSC_SLOW_CLK这四个低频时钟源提供。我们可操作LP_CLKRST_LP_CLK_CONF_REG寄存器中的第0~1位(即LP_CLKRST_SLOW_CLK_SEL字段)来选择时钟源。下图是派生的LP时钟源。

图2.4.1.3 派生的LP时钟源
上图中,左边“Source Clock”为原始时钟源,右边“Derived Clock”为派生时钟源(由原始时钟源经过分频得到)。下图为LP系统外设时钟源选择。

图2.4.1.4 LP系统外设时钟源选择
关于ESP32-P4的LP系统外设时钟源选择,可以参考《eESP32-P4技术参考手册》中的455页8.2-7表格。

2.4.2 系统与内存

在ESP32-P4芯片中,系统架构设计和内存布局为高效处理和多任务并发提供了基础。前面讲解过,该芯片集成了高性能(HP)和低功耗(LP)两种RISC-V处理器,配合多级内存结构与丰富的外设支持,适用于各种物联网和嵌入式应用场景。
下图展示了ESP32-P4的系统结构和地址映射。ESP32-P4的指令总线和数据总线共享同一地址空间,这意味着所有非保留的地址都可以通过这两条总线进行访问。这种设计提高了系统在执行指令和访问数据时的灵活性。在分析下图之前,我们需要先了解两个关键概念:总线结构与端序,以及数据访问对齐。
1,总线结构与端序
在ESP32-P4中,HP CPU和LP CPU的指令总线和数据总线均采用小端序(little-endian)。其中,HP CPU的数据总线(DBUS)具有128位的数据宽度,而其他总线的数据宽度为32位。
2,数据访问对齐
1)HP CPU:通过数据总线访问数据时,支持单字节(1字节)、双字节(2字节)和4字节对齐。此外,在执行AI指令时,HP CPU的数据对齐需求最高可达16字节,这为高效的AI计算提供了支持。
2)LP CPU:支持单字节、双字节和4字节对齐的数据访问。
这种对齐方式的设计,尤其是HP CPU的多字节对齐支持,使得ESP32-P4在高性能计算和数据处理任务中能够更有效地利用内存带宽和系统资源。

图2.4.2.1 ESP32-P4 系统结构与地址映射
上图展示了ESP32-P4的系统结构和地址映射。以下是对该图所示系统结构和地址映射的逐步解剖。

1,处理器结构
ESP32-P4芯片包含以下两种处理器:
1)高性能(HP)CPU:32位RISC-V双核处理器,主频高达400 MHz,采用五级流水线结构。HP CPU适用于计算密集型任务,支持对高速缓存和大容量外部存储的快速访问。
2)低功耗(LP)CPU:32位RISC-V单核处理器,主频40 MHz,采用两级流水线结构。LP CPU功耗较低,适合执行低速率、低功耗任务,通常用于待机或低频应用。
这种双处理器架构允许系统在功耗和性能之间灵活切换,为任务分配和资源管理提供了更高的灵活性。

2,内存结构
ESP32-P4的内存结构由多层次的内部存储器和可外扩的存储器组成,允许高效的数据处理和存储访问。
1)HP CPU内存访问:
HP TCM(紧耦合内存):8 KB,地址范围为0x30100000~0x30101FFF,供HP CPU快速访问,适合存储时间敏感的数据或指令。
①:HP ROM(只读存储器):128 KB,分为两种访问方式,一种是缓存访问地址,通过Cache进行缓存访问(0x4FC000000x4FC1FFFF),另一种是直接访问地址(0x8FC000000x8FC1FFFF)。HP ROM存储区是用于系统启动代码和初始化程序。
②:HP L2MEM(二级缓存内存):768 KB,分为两种访问方式,一种是缓存访问地址(0x4FF000000x4FFBFFFF),另一种是直接访问地址(0x8FF000000x8FFBFFFF)。
③:外部存储器:
外部Flash(External flash):最大64 MB,供程序代码和非易失性数据存储,地址范围为:
缓存访问地址:0x40000000~0x43FFFFFF。
直接访问地址:0x80000000~0x83FFFFFF。
外部RAM(External RAM):最大64 MB,适合存储大量数据或临时缓存,地址范围为:
缓存访问地址:0x48000000~0x4BFFFFFF。
直接访问地址:0x88000000~0x8BFFFFFF。
2)LP CPU内存访问:
①:LP ROM:16 KB,地址范围为0x50100000~0x50103FFF,存储启动代码和初始化程序。
②:LP SRAM:32 KB,地址范围为0x50108000~0x5010FFFF,为LP CPU提供的低功耗快速访问存储。
③:共享访问:LP CPU还可以访问HP ROM、HP L2MEM和外部存储器(地址与HP CPU相同),从而增强数据共享和协同处理能力。

3,外设地址映射
ESP32-P4芯片的外设模块具有独立的地址空间,为处理器和外设间的通信提供了便利。
1)HP CPU外设:地址范围为0x3FF00000~0x3FF1FFFF。
2)HP外设:地址范围为0x50000000~0x500FFFFF。
3)LP外设:地址范围为0x50110000~0x5012FFFF。
通过这种独立的地址划分,ESP32-P4的处理器能够高效管理多个外设,减少总线冲突,并优化访问延迟。关于外设地址映射的详细信息,请参考《ESP32-P4技术参考手册》第5章《System and Memory》中的5.3.5小节《Modules/Peripherals Address Mapping》,该小节已详细讲解了各个外设的映射地址。

4,地址配置
ESP32-P4内存的地址空间可以通过不同方式进行访问,其中缓存访问和直接访问的分布设计可以满足不同任务的需求:
1)缓存访问:地址以0x4xxx_xxxx开头的区域可以配置为缓存访问,通过处理器的PMU(性能监控单元)进行管理,以提高访问速度。
2)直接访问:地址以0x8xxx_xxxx开头的区域提供直接访问,通常用于调试或需要低延迟访问的场景。
通过这种灵活的访问配置,ESP32-P4芯片支持在不同存储设备和数据类型之间快速切换,提升了数据的读取和写入效率。
至此,ESP32-P4的系统与内存相关知识讲解完毕。如需深入了解更多系统与内存的细节,请参考《ESP32-P4技术参考手册》中的第5章《System and Memory》。

2.4.3 IO MUX和GPIO交换矩阵

GPIO(通用输入输出)引脚作为芯片与外部设备交互的关键接口,为了支持多种外设和应用需求,GPIO引脚需要灵活地连接到不同的外设信号上。ESP32-P4芯片通过高功率(HP)和低功率(LP)两种GPIO矩阵和IO MUX(输入输出复用器)系统,实现了对GPIO引脚的灵活配置,使其可以与多达数百个外设信号相互连接,并且可以支持信号同步、滤波、直连等多种功能。了解IO MUX和GPIO矩阵的架构和功能,有助于开发者灵活配置ESP32-P4的引脚资源,满足不同应用场景的需求。
本章节将详细介绍ESP32-P4中的HP和LP GPIO矩阵以及对应的IO MUX的工作原理、架构以及信号的路由方式,并对其主要特性进行分析。下图为ESP32-P4的IO MUX和GPIO交换矩阵整体框架。

图2.4.3.1 IO MUX和GPIO交换矩阵整体框架
上图是ESP32-P4的HP GPIO矩阵、HP IO MUX、LP GPIO矩阵和LP IO MUX的结构,详细描述了信号从引脚到外设以及从外设到引脚的路由方式。下面我们先了解比较重要的模块相关特性,然后再去了解信号从引脚到外设和外设到引脚的路由方式。
1,HP GPIO Matrix特性
图2.4.3.1中的HP GPIO矩阵是用于将HP外设信号与GPIO引脚连接,它具有以下特点:
1)全交换矩阵:支持HP外设信号与GPIO引脚之间的全交换配置,灵活处理输入输出。
2)HP外设输入:可支持222个HP外设输入信号,灵活路由到任意GPIO引脚。这222个HP外设输入信号可查看《ESP32-P4技术参考手册》中的7.12 HP Peripheral Signal List小节内容,如下图所示。

图2.4.3.2 HP外设信号列表
上图中,左侧为HP系统的外设输入信号,而右侧为HP系统的输出信号,这些外设输入输出可使用任意IO来实现。
3)HP外设输出:支持232个HP外设输出信号,能够路由到任意GPIO引脚(请看上图右侧信号)。
4)信号同步:通过同步处理确保输入信号与HP IO MUX的工作时钟一致,稳定性高。
5)输入信号滤波:配有GPIO滤波器进行二次过滤,有效提升信号抗干扰能力。
6)简单输入输出:提供基础的GPIO输入输出功能,支持常规数字输入输出。

2,HP IO MUX特性
图2.4.3.1中的HP IO MUX是负责HP GPIO引脚的配置与管理,主要功能包括:
1)引脚控制:管理55个GPIO引脚(GPIO0 ~ GPIO54),用于HP外设的连接和控制。
2)配置寄存器:每个GPIO引脚配有配置寄存器(IO_MUX_GPIOn_REG),可控制引脚的输入输出模式、上拉/下拉、电流驱动强度及功能选择。
3)高频信号直连:对于高频信号(如SPI、EMAC),可直接通过HP IO MUX连接外设,优化高频性能。
这两部分功能紧密配合,为ESP32-P4提供了灵活的外设信号处理和GPIO管理能力。

3,LP GPIO Matrix特性
图2.4.3.1中的LP GPIO矩阵是用于LP外设信号提供了灵活的信号路由,适用于低功耗场景,具有以下功能:
1)全交换矩阵:支持LP外设输入输出信号与LP GPIO引脚之间的全交换矩阵配置。
2)LP外设输入:支持14个LP外设输入信号,可以通过LP GPIO矩阵路由到任意LP GPIO引脚,这些外设输入信号请看《ESP32-P4技术参考手册》中的7.13 LP Peripheral Signal List小节内容,如下图所示。

图2.4.3.3 LP系统的外设信号列表
上图中,左侧为LP系统的外设输入信号,而右侧为LP系统的输出信号,这些外设输入输出可使用任意IO来实现。
3)LP外设输出:支持14个LP外设输出信号,可以路由至任意LP GPIO引脚输出(请看上图右侧信号)。
4)输入信号滤波:配备GPIO滤波器,用于对输入信号进行简单的滤波处理,提高信号的稳定性。
5)简单输入输出:支持基本的GPIO输入输出功能,满足低功耗设备的输入输出需求。

4,LP IO MUX特性
图2.4.3.1中的LP IO MUX是负责LP GPIO引脚的配置与管理,它的功能包括:
1)引脚控制:管理16个LP GPIO引脚(GPIO0 ~ GPIO15),用于LP外设的连接和控制。
2)配置寄存器:每个LP GPIO引脚配有配置寄存器(LP_IOMUX_PADn_REG),可用于控制引脚的输入输出模式、上拉/下拉、电流驱动强度、功能选择和IO MUX选择。

5,管脚PAD类型
在图2.4.3.1中,ESP32-P4芯片的PAD管脚类型分为两类电源域:VDDPST1和VDDPST2VDDPST6。VDDPST1电源域负责管理GPIO0GPIO15号管脚的电源,而VDDPST2VDDPST6电源域则负责管理GPIO16GPIO54号管脚的电源。之所以将管脚分为两类电源域,是因为ESP32-P4在不同工作模式下对电源管理有不同的需求。在低功耗(LP)模式下,芯片只能使用由VDDPST1电源域管理的GPIO0GPIO15管脚,以最大限度减少功耗。而在高性能(HP)模式下,芯片可以使用VDDPST1到VDDPST6电源域管理的管脚,即可使用GPIO0GPIO54的全部55个可编程I/O管脚,满足更复杂的I/O需求。这种电源域的划分使得ESP32-P4能够根据不同的工作状态灵活地管理功耗,同时提供丰富的I/O资源来支持多种应用。下面为VDDPST1到VDDPST6电源域管理的管脚范围,如下图所示。

图2.4.3.4 电源域管理的GPIO(部分截图)
上图的列表摘自《ESP32-P4数据手册》中的2.2 Pin Overview小节,表格详细阐述了各个电源域管理的GPIO管脚。通过控制这些电源域的电压,我们可以相应地控制它们所管理的GPIO的输入输出电压。具体来说,VDDPST1电源域管理的GPIO(GPIO0GPIO15)和VDDPST2VDDPST6电源域管理的GPIO(GPIO16~GPIO54)在工作时可根据不同电源域的电压调节来控制相应管脚的电平状态,从而实现精确的电压控制与信号处理。
至此,我们已了解了ESP32-P4的IO MUX和GPIO交换矩阵各个模块的功能与特性,接下来我们将介绍如何配置GPIO管脚为输入或输出,并将其分别与输入信号和输出信号进行绑定。

6,管脚的输入输出配置
从上述内容可以看出,配置ESP32-P4的55个可编程I/O管脚的输入输出模式,需要通过配置IO_MUX_GPIOx_REG和LP_IOMUX_PADx_REG寄存器来实现。其中,IO_MUX_GPIOx_REG寄存器用于配置HP系统中所有55个可编程I/O管脚的电气特性,而LP_IOMUX_PADx_REG寄存器仅能用于配置GPIO0~GPIO15号管脚的I/O功能,适用于低功耗模式下的配置。接下来,笔者将以HP系统为例,介绍如何配置这些管脚。
下图为管脚PAD内部结构,如下图所示。

图2.4.3.4 GPIO0~GPIO54的PAD内部结构
上图展示了PAD焊盘内部结构的输入/输出、上拉/下拉等配置,这些配置可以通过IO_MUX_GPIOx_REG(x:0~54)寄存器来实现。该寄存器用于设置与GPIO相关的电气属性,如输入输出模式、上拉或下拉电阻等。具体的寄存器描述和配置细节如下图所示。

图2.4.3.5 配置GPIO输入配置
上图中,WPD和WPU字段用于配置GPIO的上下拉使能;IE和DRV字段用于配置GPIO的输入使能与驱动能力;SEL和EN字段用于配置GPIO功能和是否启动滤波器。输出配置是由GPIO_ENABLE_REG寄存器配置的,大家可参看《ESP32-P4技术参考手册》中的7.12 HP Peripheral Signal List小节内容。

7,管脚路由至内部外设信号
从图2.4.3.1中可以看出,若GPIO由VDDPST2~VDDPST6电源域管理,则该GPIO的输入信号会流经两个方向:一条是HP IO MUX,另一条是HP GPIO matrix交换矩阵。而若GPIO由VDDPST1电源域管理,则该GPIO的输入信号可流经四个方向:首先是HP IO MUX,其次是HP GPIO matrix交换矩阵,另外在系统处于低功耗模式(即LP系统)时,信号还将流入LP IO MUX和LP GPIO matrix交换矩阵。这些信号流向的方向可参考图2.4.3.1中的红色(③)箭头。
接下来,笔者以VDDPST2~VDDPST6电源域管理的GPIO为例进行说明。
1)若输入信号被选择输入到HP IO MUX,则必须首先选择该GPIO的功能,并将其直接连接至CPU内部外设信号。下图展示了可供选择的GPIO功能,这些功能可以通过配置IO_MUX_GPIOn_REG寄存器来实现。

图2.4.3.6 IO MUX的GPIO选择功能(部分截图)
上图摘自《ESP32-P4数据手册》中的2.3.1 IO MUX Functions小节内容。上图中,若我们把GPIO28号管脚配置为Function3功能,则该GPIO通过IO MUX直接连接至SPI2_CS_PAD内部外设信号(请看图2.4.3.1中的⑥和①)。
2)当输入信号被选择进入高性能(HP)GPIO矩阵时,该信号会依次经过信号滤波和毛刺滤波处理,然后通过GPIO_EXT_GLITCH_FILTER_CHn_REG寄存器配置特定的GPIO输入。此寄存器用于选择对哪个GPIO信号应用毛刺滤波,以去除可能存在的短时噪声信号或毛刺信号,从而提升信号的稳定性和可靠性。经过滤波处理的信号还会进行时钟同步(GPIO SYNC),确保信号与系统时钟保持一致性,减少由于时钟不匹配可能引入的延迟或不稳定因素。同步处理完成后,信号将进入内部信号绑定模块,用于后续的逻辑控制或输出。如下图所示,通过GPIO_EXT_GLITCH_FILTER_CHn_REG(n:0~7)寄存器配置哪个GPIO输入字段描述。

图2.4.3.7 配置哪个GPIO输入信号
3)通过GPIO_FUNCn_IN_SEL配置输入信号时,可参考图2.4.3.1中的步骤②。例如,若要将UART0的RXD输入信号(信号索引为10)连接到GPIO7,请按以下步骤配置。
设置GPIO_FUNC10_IN_SEL_CFG_REG寄存器(n表示图2.4.3.2中的索引号,对应uart0_rxd_pad_in输入信号)中的GPIO_SIG10_IN_SEL位,以通过HP GPIO矩阵启用外设输入。这样可以通过矩阵将信号索引10(即UART0的RXD输入)路由到一个GPIO上。然后在GPIO_FUNC10_IN_SEL_CFG_REG寄存器中,将GPIO_FUNC10_IN_SEL字段设置为7,指定GPIO7作为UART0 RXD信号的输入源,最后配置IO_MUX_GPIO7_REG寄存器中的IO_MUX_GPIO7_FUN_IE位(具体描述见图2.4.3.5中左则的外部信号),以启用GPIO7的引脚输入。此设置允许引脚从HP GPIO矩阵接收输入信号。上述用到的寄存器的字段描述如下所示。

图2.4.3.8 配置GPIO映射到内部输入信号
至此,GPIO路由至内部输入信号的流程已讲解完成。对于LP系统,流程与HP系统类似,只是配置的寄存器不同。

8,内部外设信号路由至管脚
接下来,笔者将以HP系统的内部外设信号输出为例进行说明。如图2.4.3.1所示,HP系统中的232个外设信号可以通过HP GPIO matrix 和HP IO MUX输出。如果选择通过HP GPIO matrix输出外设信号(请看图2.4.3.1中的⑧),则必须配置对应的寄存器,即GPIO_FUNCn_OUT_SEL_CFG_REG寄存器,其中n表示图2.4.3.2右侧列出的外部信号编号,共有232个外部输出信号。以下是GPIO_FUNCn_OUT_SEL_CFG_REG寄存器的字段描述。

图2.4.3.9 内部外设输出信号绑定GPIO
如果选择直接输出外设信号,则信号会通过HP IO MUX的直接映射功能输出。这些映射功能我们已经在图2.4.3.6中进行了详细说明。要实现直接输出的配置,只需设置对应的IO_MUX_GPIOn_REG寄存器,即可完成信号的输出。
至此,内部输出信号路由至GPIO的流程已讲解完成。对于LP系统,流程与HP系统类似,也 是配置的寄存器不同。

2.4.4 芯片Boot控制

芯片在上电或硬件复位时,会通过某些管脚的上下拉(Strapping Pins)和eFuse bits(是一种可编程电子保险丝,是一种用于存储信息和保护芯片的非易失性存储器件)来确定其启动过程和一些功能,无需微处理器的参与。这些设置可以决定以下功能:
1)芯片启动模式:确定芯片以何种模式启动。
2)ROM消息打印的启动和禁用:决定是否在启动时打印ROM中的消息。
3)JTAG信号源:决定JTAG信号的来源。
1,芯片启动模式。
在电源上电或复位过程中,芯片会采集Strapping管脚(GPIO35、GPIO36、GPIO37、GPIO38)的电平状态,存储在锁存器中并保持至断电。下表是芯片启动模式控制。

表2.4.4.1 芯片启动模式控制
ESP32-P4芯片的启动模式由GPIO35至GPIO38的电平决定。默认情况下,若GPIO35为高电平,则芯片进入“SPI Boot”模式;若GPIO35为低电平且GPIO36为高电平,则进入“Joint Download Boot”模式,支持“USB”、“UART”和“SPI Slave”三种下载方式;若GPIO35至GPIO37均为低电平且GPIO38为高电平,则芯片进入“SPI Download Boot”模式;若GPIO35至GPIO38均为低电平,则芯片进入“Invalid Combination”无效模式。下图为Strapping管脚默认电平。

图2.4.4.1 Strapping管脚默认电平
根据上图所示,ESP32-P4芯片的GPIO35管脚在默认情况下内部连接有一个上拉电阻,这种配置使得芯片进入“SPI Boot”模式。若GPIO35管脚未连接或连接到外部高阻抗电路,那么内部的弱上拉电阻将确定该管脚的默认输入电平,进而决定芯片的默认启动模式。下图是芯片启动流程。

图2.4.4.2 ESP32-P4芯片启动流程
注意:上图中的“x1”和“01”表示GPIO35和GPIO36组合值,芯片根据这两个管脚组合值进入不同的启动模式。
小知识:
1)Strapping管脚是芯片每次上电或复位时,都需要一些初始配置参数,如加载芯片的启动模式、flash存储器的电压等。这些参数通过strapping管脚控制。芯片读取Strapping管脚上电时的状态来配置芯片的初始化的参数,复位释放后, strapping管脚和普通IO管脚功能相同。
2)在SPI Boot模式下,ROM引导加载程序通过从SPI flash中读取程序来启动系统。在这个模式下,我们还可以进一步分类如下:
①:Normal flash Boot:ROM引导加载程序通过从SPI Flash加载至L2MEM中启动。
②:Direct Boot:程序从Flash运行。如果要启动此模式,请确保下载的bin文件前两个字为0xaedb041d。
3)在Joint Download Boot模式下,用户可通过USB或UART0接口将二进制文件下载至flash,或者下载至L2MEM中直接运行。
4)在SPI Download Boot模式下,用户可通过SPI接口将二进制文件下载至Flash,或者下载至L2MEM中直接运行。
2,ROM消息打印的启动和禁用
系统启动过程中,ROM代码log可打印至如下控制器。
1)UART0和USB Serial/JTAG控制器(默认)
2)USB Serial/JTAG控制器
3)UART0
EFUSE_UART_PRINT_CONTROL(eFuse 位)和GPIO36控制ROM消息打印到UART0,如下图所示。

图2.4.4.3 UART0 ROM 日志打印控制
EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT(eFuse 位)用于控制 ROM 日志是否打印到 USB Serial/JTAG 控制器。当该位为 1 时,禁止将日志打印到 UART Serial/JTAG 控制器。当该位为 0 时,如果通过 EFUSE_DIS_USB_SERIAL_JTAG 启用 USB Serial/JTAG 控制器,则 ROM 消息将打印到 USB 串口/JTAG 控制器。具体情况如下图所示。

图2.4.4.4 USB 串口/JTAG ROM 日志打印控制
默认情况下,EFUSE_UART_PRINT_CONTROL(eFuse 位)和 EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT(eFuse 位)均配置为 0,表示启用 UART0 和 USB Serial/JTAG ROM 日志打印功能。请注意,如果 EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT 设置为 0 以打印到 USB,但 USB Serial/JTAG 控制器已禁用,则 ROM 消息将不会打印到 USB Serial/JTAG 控制器。
有关 eFuse 控制器的详细信息,请参阅《ESP32-P4 Technical Reference Manual》中的第 292 页“eFuse Controller”章节,该章节提供了关于 eFuse 控制器的技术规格和功能说明。
3,JTAG信号源
在系统启动的早期,GPIO34可用于控制JTAG信号源。该引脚没有内部上下拉电阻,因此strapping的值必须由不处于高阻抗状态的外部电路控制。如下表所示,GPIO34与EFUSE_DIS_PAD_JTAG、EFUSE_DIS_USB_JTAG和EFUSE_JTAG_SEL_ENABLE共同控制JTAG信号源。

图2.4.4.2 JTAG信号源控制
上图中的 eFuse 1、eFuse 2 和 eFuse 3 分别代表 eFuse 位的 EFUSE_DIS_PAD_JTAG、EFUSE_DIS_USB_JTAG 和 EFUSE_JTAG_SEL_ENABLE。这里的 x 代表任意值,可以忽略。

2.4.5 中断矩阵

ESP32-P4 拥有多达 126个外设中断源,需要通过中断矩阵将这些中断信号映射到 32个HP CPU0中断 或 32个HP CPU1中断。若没有中断矩阵,这样大规模的中断源管理将极具复杂性。而通过中断矩阵,不仅能有效地将中断源分配到不同的CPU核,还可以根据应用需求将同一中断源路由至多个CPU中断输入,从而实现灵活的中断处理和多任务并行操作。通过这种结构设计,ESP32-P4的中断矩阵确保了复杂的外设中断管理变得高效、灵活且可扩展,为开发者提供了更多的系统配置选项,优化了系统性能和响应能力。
关于ESP32-P4的这126个外设中断源的详细信息,可以参考 《ESP32-P4技术参考手册》中的593页,其中的表10.4-1 描述了 CPU外设中断源映射/状态寄存器和外设中断源,为开发者提供了详细的中断源配置和映射方式。
1,中断矩阵概述
中断矩阵是一种灵活的硬件机制,用于管理和分配系统中断信号,使得多个外设的中断请求能够灵活地映射到不同的CPU中断输入上。在ESP32-P4芯片中,中断矩阵允许通过软件配置,将不同外设或GPIO引脚的中断源动态连接到特定的CPU中断控制器(Interrupt Controller)。
中断矩阵的主要功能在于其高度灵活性和可配置性,具体包括:
1)动态路由中断源:中断矩阵可以将不同的外设或GPIO中断信号连接到任意CPU核心的中断通道上,支持跨核中断分配。
2)优先级管理:矩阵允许对不同的中断源设置优先级,以确保高优先级中断能够抢占低优先级中断,提高系统的实时性。
3)中断源隔离:它支持通过矩阵的配置隔离不同的中断源,避免多个中断源竞争同一中断通道,从而提升系统的稳定性和鲁棒性。
4)可查询当前外设中断源的中断状态。
5)多个中断源可映射到单个HP CPU0或HP CPU1中断,我们称之为共享中断。
下图为ESP32-P4芯片中断矩阵结构。

图2.4.5.1 中断矩阵结构
上图中的蓝色框表示中断矩阵,它负责接收来自外设的中断信号,包括低功耗外设(LP Peripheral Interrupt Sources)和高性能外设(HP Peripheral Interrupt Sources)。当中断矩阵接收到这些外设中断信号后,用户可以通过配置红色框标识的 Core0 Interrupt Reg 或 Core1 Interrupt Reg 寄存器,来选择将外设中断源路由到 HP CPU0 或 HP CPU1。
红色框中的 Core0 Interrupt Reg 和Core1 Interrupt Reg寄存器具有两个主要功能:
1)上图中的①,通过配置端口(Config Port) 动态地将中断信号路由到特定核心的中断控制器,允许用户灵活配置中断路由。
2)上图中的②,通过状态端口(Status Port) 查询当前外设中断源的状态,帮助用户监控和调试中断的处理情况。
上图中的绿色框标识表示 Core0 Interrupt Ctrl 和Core1 Interrupt Ctrl中断控制器,它负责处理路由到该核心的中断信号。这些控制器可以根据中断优先级、信号来源等条件,决定是否处理中断。最终,当CPU接收到外部中断信号时,会调用与该中断相关联的中断服务程序(上图的橙色框标识),处理完毕后,恢复正常操作。
2,中断矩阵的操作流程
1)中断信号生成:当某个外设或GPIO产生中断事件时,信号传递至中断矩阵。
2)信号路由:中断矩阵根据预设的路由配置,将中断信号映射至目标CPU的中断输入端。
3)CPU中断处理:CPU接收到中断信号后,根据中断优先级判定是否处理该中断。当中断处理完成后,CPU通过清除相应标志位或通过软件控制的中断服务恢复正常执行流程。
下图为中断处理流程图。

图2.4.5.1 中断处理流程
在 ESP32-P4 中,外设模块可以生成多达126个内部中断源,这些中断源对应于不同的外设事件或状态变化,如计时器溢出、串口数据接收完成、GPIO信号变化等。这些中断源首先通过硬件生成 126条中断信号(Interrupt Signals)。
接下来,这些外设中断信号被发送到中断矩阵(Interrupt Matrix),一个用于灵活管理和分配中断信号的硬件结构。中断矩阵将外设的中断信号转化为 中断源(Interrupt Sources),并根据系统配置将其路由到适当的CPU核上的中断控制器。
上图中的中断控制器的任务是根据系统设计和开发者的配置,将这 126个外设中断源路由到 32条CPU中断通道,这些通道分别与ESP32-P4的不同CPU核(CPU0和CPU1)相对应。当中断矩阵将中断源映射到相应的CPU中断信号时,信号最终会进入 HP CPU中断控制器。该控制器负责进一步管理和处理来自中断矩阵的信号,并根据中断的优先级做出处理决策。当中断控制器决定处理某个中断时,CPU会暂停当前任务,执行与中断相关的中断服务例程(ISR)。中断处理完成后,系统将恢复正常任务执行,并清除中断标志,确保系统顺利运行。
下图为中断矩阵管理的CPU外设中断源映射和状态寄存器。

图2.4.5.2 CPU外设中断源映射和状态寄存器(部分截图)
读者可在《ESP32-P4技术参考手册》中的“Interrupt Matrix”章节中,参考表10.4.1,找到关于CPU外设中断源映射和状态寄存器的详细内容。该表格列出了所有可用的中断源及其映射关系,有助于理解中断系统的工作机制和配置方法。

2.5 ESP32-P4 启动流程

本文将会介绍ESP32-P4从上电到运行app_main函数中间所经历的步骤(即启动流程)。从宏观上,该启动流程可分为如下三个步骤。
1)一级引导程序,它被固化在ESP32-P4内部的ROM中,它会从flash的0x2000处地址加载二级引导程序至RAM(IRAM & DRAM)中。
2)二级引导程序从flash中加载分区表和主程序镜像至内存中,主程序中包含了RAM段和通过flash高速缓存映射的只读段。
3)应用程序启动阶段运行,这时第二个CPU和freeRTOS的调度器启动,接着运行main_task任务函数,从而进入app_main函数执行用户代码。
下面作者根据IDF库相关的代码来讲解这三个引导流程,如下:
1,一级引导程序
该部分程序是直接存储在ESP32-P4内部ROM中,所以普通开发者无法直接查看,它主要是做一些前期的准备工作(复位向量代码),然后从flash 0x2000偏移地址中读取二级引导程序文件头中的配置信息,并使用这些信息来加载剩余的二级引导程序。
2,二级引导程序
该程序是可以查看且可被修改,在搭建ESP-IDF环境完成后,可在esp-idf\components\bootloader/subproject/main/路径下找到bootloader_start.c文件,此文件就是二级引导程序启动处。首先我们克隆ESP-IDF库,克隆过程如下所示。

图2.6.1 克隆ESP-IDF库
克隆完成后,使用VSCode打开ESP-IDF库,接着找到bootloader_start.c,如下图所示。

图2.6.2 bootloader_start.c文件路径
在这个文件下,找到call_start_cpu0函数,此函数是bootloader程序,如下是bootloader程序的部分代码。

/*
 ROM引导加载程序完成从闪存加载第二阶段引导加载程序之后到达这里
 */
void __attribute__((noreturn)) call_start_cpu0(void)
{
    if (bootloader_before_init) {
        bootloader_before_init();
    }

/* 1. 硬件初始化:初始化内存、启用超级看门狗自动喂养、配置时钟、清除bss段、开启cache和
复位mmu等操作。
bootloader_support/src/ esp32-p4/bootloader_esp32p4.c */
    if (bootloader_init() != ESP_OK) {
        bootloader_reset();
    }

    if (bootloader_after_init) {
        bootloader_after_init();
    }

    /* 2. 选择启动分区的数量:加载分区表,选择boot分区 */
    bootloader_state_t bs = {0};
    int boot_index = select_partition_number(&bs);
    
    if (boot_index == INVALID_INDEX){
        bootloader_reset();
    }

/* 3. 加载应用程序映像并启动
bootloader_support/src/esp32-p4/bootloader_utility.c */
    bootloader_utility_load_boot_image(&bs, boot_index);
}

ESP-IDF使用二级引导程序可以增加FLASH分区的灵活性(使用分区表),并且方便实现FLASH加密,安全引导和空中升级(OTA)等功能。主要的作用是从flash的0x8000处加载分区表(请看在线ESP-IDF编程指南分区表章节)。根据分区表运行应用程序。
3,三级引导程序
应用程序的入口是在esp-idf/components/esp_system/port/路径下的cpu_star.c文件,在此文件下找到call_start_cpu0函数(端口层初始化函数)。这个函数由二级引导加载程序执行,并且从不返回。因此你看不到是哪个函数调用了它,它是从汇编的最底层直接调用的(components\esp_system\ld\esp32p4\sections.ld.in汇编文件)。
这个函数会初始化基本的C运行环境(“CRT”),并对SOC的内部硬件进行了初始配置。执行call_start_cpu0函数完成之后,在components\esp_system\startup.c文件下调用start_cpu0(在36行中,弱关联start_cpu0_default函数)系统层初始化函数,如下start_cpu0_default函数的部分代码。

static void start_cpu0_default(void)
{
    /* 初始化核心组件和服务 */
    do_core_init();

    /* 执行构造函数 */
    do_global_ctors();

    /* 执行其他组件的init函数 */
do_secondary_init();

#if SOC_CPU_CORES_NUM > 1 && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
    s_system_full_inited = true;
#endif

    /* 开启APP程序 */
    esp_startup_start_app();
    while (1);
}

到了这里,就完成了二级程序引导,并调用esp_startup_start_app函数进入三级引导程序,该函数的源码如下:

/* components/freertos/app_startup.c */
/* 开启APP程序 */
void esp_startup_start_app(void)
{
    /* 省略部分代码 */

    /* 新建main任务函数 */
    BaseType_t res = xTaskCreatePinnedToCore(main_task, "main",
                                             ESP_TASK_MAIN_STACK, NULL,
                                             ESP_TASK_MAIN_PRIO, NULL,
                                             ESP_TASK_MAIN_CORE);
    assert(res == pdTRUE);
    (void)res;

    void __attribute__((weak)) port_start_app_hook(void);
    if (port_start_app_hook != NULL) {
        port_start_app_hook();
    }

    ESP_EARLY_LOGD(APP_START_TAG, "Starting scheduler on CPU0");
    /* 开启FreeRTOS任务调度 */
    vTaskStartScheduler();
}

/* main任务函数 */
static void main_task(void* args)
{   /* 省略部分代码 */
    /* 执行app_main函数 */
    ESP_LOGI(MAIN_TAG, "Calling app_main()");
    extern void app_main(void);
    app_main();
    ESP_LOGI(MAIN_TAG, "Returned from app_main()");
    vTaskDelete(NULL);
}

从上述源码可知,首先在xTaskCreatePinnedToCore函数创建main_task任务,然后开启freeRTOS任务调度器,最后在main_task任务下调用app_main函数(此函数在创建工程时,在main.c下定义的)。

作者:齐海智

一、背景:大促备战中的异常数据

大促备战期间,接到客户反馈我司上传到客户服务器上的文件存在科学计数法表示的情况(下图的4.55058496E7),与约定不符。

在这里插入图片描述



查看转换前的数据是:455058496,转换后(除以10:进行毫米到厘米的转换)就变成了科学计数法形式了。

在这里插入图片描述

问题代码:

<set var="temp.b" expr="${_item.boxLength / 10}" clazz="java.lang.String"/>

说明:

这个是个EL表达式,含义是使用expr的值作为计算逻辑,计算结果赋值给var指向的变量temp.b,类型是java.lang.String。

_item代表当前上下文里的一个对象。

boxLength_item对象所具备的属性。

•该表达式先对boxLength执行除以 10 的运算,再把运算结果转换为字符串(由clazz定义的)。

业务上,boxLength是个长度的概念,单位是毫米,除以10是转换成厘米的含义。为了保证精度,系统(基于JAVA)会先将boxLength先转成java.lang.Double类型,再除以10,最后调用Double.toString()方法转成字符串。

二、问题定位:字符串转换的科学计数法陷阱

2.1 问题复现

代码:

Double depthInDouble = 455058496d/10;
log.info("depthInDouble={}", depthInDouble);

结果:

在这里插入图片描述



2.2 原因分析

问题就出在了最后一行,日志输出的时候Double会被转成String,调用Double.toString()方法,而对于Double对象的值在一定的范围内,会使用科学计数法表示。

log.info的调用链(为什么会调用到Double.toStirng()):

log.info("depthInDouble={}", depthInDouble);
  ↓
Log4jLogger.info(String format, Object arg)
  ↓
AbstractLogger.logIfEnabled(...)
  ↓
AbstractLogger.logMessage(...)
  ↓
ParameterizedMessageFactory.newMessage(...)
  ↓
ParameterizedMessage 构造函数(参数被暂存为 Object[])
  ↓
// 此时尚未调用 Double.toString()
  ↓
// 当 Appender 执行输出时...
Appender.append(LogEvent)
  ↓
LogEvent.getMessage().getFormattedMessage() // 触发消息格式化
  ↓
ParameterizedMessage.getFormattedMessage()
  ↓
ParameterizedMessage.formatMessage(...)
  ↓
ParameterizedMessage.argToString(Object)
  ↓
Double.toString() // 终于在这里被调用!

查看Double.toString()的源码,可以看到相关解释:

在这里插入图片描述

也就是说对于极小(小于10^-3)或者极大(大于10^7)值的浮点数,转成String的时候会使用科学计数法表示,验证如下。

代码:

public static void main(String args[]) {
       String depth = "455058496"; // 单位:毫米
       Double depthInDouble = Double.parseDouble(depth)/10;
       String doubleInString = String.valueOf(depthInDouble);
       log.info("depthInDouble={}", depthInDouble);
       log.info("doubleInString={}", doubleInString);
       depthInDouble = 1e-3;
       log.info("10^-3 = {}", depthInDouble);
       depthInDouble = 1e7;
       log.info("10^7 = {}", depthInDouble);
       Double aVerySmallNumber = 1e-9;
       depthInDouble = 1e-3 - aVerySmallNumber;
       log.info("10^-3 - delta = {}", depthInDouble);
       depthInDouble = 1e7 - aVerySmallNumber;
       log.info("10^7 - delta = {}", depthInDouble);
   }

运行结果:

在这里插入图片描述



说明,10^-3不会使用科学记计数法,但是小于它就会使用科学计数法,10^7就会使用科学计数法,小于它就会不会,大于它会。

2.3 为什么要使用科学计数法

2.3.1 小数在计算机内是如何表示的

先不急于讨论为什么使用科学计数法,我们先看看小数在计算机内是如何表示的。

从存储角度来看,计算机的存储是有限资源,能存储的数据是有范围的,不是无限大,也就是说有限的硬件资源限制了计算机可以表示的数值的大小。对于一个浮点数,我们可以用10个bit存储,也可以用100个,为了实现跨设备、跨平台的数据统一表示和交换,IEEE 754 规范定义了标准格式,规定了Double类型使用64比特。

在这里插入图片描述

当64个比特确定了,那么它可以表示的数字的范围就确定了,接下来考虑怎么表示小数,可以表示什么范围内的小数,进而再讨论威慑么定义超过10^7或者小于10^-3使用科学计数法,而不用普通的方式(定点数表示法)。

类似整数可以利用除以2取余获得其二级制的表示形式,例如:123(10进制)= 1111011(二进制)

在这里插入图片描述



小数则进行乘2取整,如0.123(10进制)= 0. 0001111101(二进制,位数会一直循环无法精确表示,只能近似,这里取了10位)

在这里插入图片描述

因此最简单的一种设计(不考虑正负)就是将64位中的一部分划分为整数位,一部分划分为小数位,比如32位整数,32位小数(定点数表示法)。

那么这样设计的Double最大数可以表示2^32-1,

如果要以米为单位表示银河系直径,约1光年299792458米/秒1年 = 299792458米/秒365天*86400秒/天 ≈ 9.45 * 10^15 ,而2^32-1≈4.29 * 10^9 (远小于1光年),因此无法使用Double表示银河系直径,无法支撑天文学科的计算了。

在这里插入图片描述



这样设计的Double最小可以表示2^-32=2.3810^-10 ,一个质子的大小是0.84飞米=8.410^-16,因此也无法支持物理学的计算。

所以,矛盾在于增加整数部分的位数,就会压缩小数部分的位数,不同的领域中,既有要求数字很大可表示的(在乎量级,如天文学、金融学),也有要求数值很小能表示的(在乎精度,如物理学、生物学)。

可以看到,上面的很多数字表达,我们也使用了科学计数法的表示形式来简化表达,对于上面这个数字(9.454,254,955,488,000)写起来麻烦还很占地方,而且我们也不需要那么精确,只是看个量级,因此会写成9.45 * 10^15 ,不影响理解。

即表示一个极大或者极小的数可以使用:【数值底数^指数】的形式,对于大数来讲指数就是正的,小数就是负的,计算机使用二进制,因此底数就是2,所以小数可以表示成:【数值2^指数】的形式,这个数值,其实就是尾数。

计算机专家们经过多种研究,最终经过IEEE确定了IEEE 754标准,即不确定整数和小数的位数(固定小数点,即定点数),而使用变化的位数,也就是小数点可以浮动,即浮点数表示法。浮点数表示法定义了小数由符号位+指数位+尾数位三部分组成。

符号位是1bit,0代表整数,1代表负数,指数位决定数值的量级,尾数位决定数值精度。

64位的说明如下:

在这里插入图片描述





其中11和52的设计是在平衡了很多需求后得到的最佳实践。

Double (64位) = 符号位(1位) + 指数位(11位) + 尾数位(52位)

示例:455058496.0 的IEEE 754表示
原始值:455058496.0
二进制科学计数法:1.0101100001110000000000000000000 × 2^28

符号位:0 (正数)
指数位:28 + 1023(偏移量) = 1051 = 10000011011₂
尾数位:0101100001110000000000000000000... (52位)

完整64位表示:
0 10000011011 0101100001110000000000000000000000000000000000000000

2.3.2 数值超过10^7或者小于10^-3会发生什么

其实什么也不会发生,只是基于如下原因综合权衡的结果。

1、认知科学依据

•人类短期记忆的数字处理能力约为7±2位

•超过7位的整数部分难以快速理解

•科学计数法提供更好的可读性

2、精度保持考虑

•10^7 = 10,000,000 (8位数字)

•超过此值,普通格式会显得冗长

•10^-3 = 0.001,更小的数用科学计数法更清晰

3、历史兼容性

•这个标准在多种编程语言中被采用

•保持了与C语言printf的兼容性

•符合IEEE 754标准的建议

这也就是为什么这个这个范围内的数要表示成科学计数法了。

2.3.3 源码探究

1、调用链路

根据源码,可以看到Double.toString()方法的调用链是:

在这里插入图片描述

分流是否使用科学计数法的核心代码toChars的代码如下:

/*
 * Formats the decimal f 10^e.
 */
private int toChars(byte[] str, int index, long f, int e, FormattedFPDecimal fd) {
    /*
     * For details not discussed here see section 10 of [1].
     *
     * Determine len such that
     *     10^(len-1) <= f < 10^len
     */
    int len = flog10pow2(Long.SIZE - numberOfLeadingZeros(f));
    if (f >= pow10(len)) {
        len += 1;
    }
    if (fd != null) {
        fd.set(f, e, len);
        return index;
    }

    /*
     * Let fp and ep be the original f and e, respectively.
     * Transform f and e to ensure
     *     10^(H-1) <= f < 10^H
     *     fp 10^ep = f 10^(e-H) = 0.f 10^e
     */
    f *= pow10(H - len);
    e += len;

    /*
     * The toChars?() methods perform left-to-right digits extraction
     * using ints, provided that the arguments are limited to 8 digits.
     * Therefore, split the H = 17 digits of f into:
     *     h = the most significant digit of f
     *     m = the next 8 most significant digits of f
     *     l = the last 8, least significant digits of f
     *
     * For n = 17, m = 8 the table in section 10 of [1] shows
     *     floor(f / 10^8) = floor(193_428_131_138_340_668 f / 2^84) =
     *     floor(floor(193_428_131_138_340_668 f / 2^64) / 2^20)
     * and for n = 9, m = 8
     *     floor(hm / 10^8) = floor(1_441_151_881 hm / 2^57)
     */
    long hm = multiplyHigh(f, 193_428_131_138_340_668L) >>> 20;
    int l = (int) (f - 100_000_000L * hm);
    int h = (int) (hm * 1_441_151_881L >>> 57);
    int m = (int) (hm - 100_000_000 * h);

    if (0 < e && e <= 7) {
        return toChars1(str, index, h, m, l, e);
    }
    if (-3 < e && e <= 0) {
        return toChars2(str, index, h, m, l, e);
    }
    return toChars3(str, index, h, m, l, e);
}

代码地址: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java

可以看到使用科学计数法处理的核心代码是toChars3,代码如下:

private int toChars3(byte[] str, int index, int h, int m, int l, int e) {
    /* -3 >= e | e > 7: computerized scientific notation */
    index = putDigit(str, index, h);
    index = putChar(str, index, '.');
    index = put8Digits(str, index, m);
    index = lowDigits(str, index, l);
    return exponent(str, index, e - 1);
}
2、toChars3()的参数含义

byte[] str: 输出字符串的字节数组

int index: 当前写入位置的索引

int h: 最高位数字 (0-9)

int m: 中间8位数字 (00000000-99999999)

int l: 低位数字 (用于精度控制)

int e: 调整后的十进制指数值

3、 toChars3()的数据流处理步骤

1.putDigit(str, index, h) → 写入最高位数字

2.putChar(str, index, '.') → 写入小数点

3.put8Digits(str, index, m) → 写入中间8位数字

4.lowDigits(str, index, l) → 写入低位数字(去除尾随零)

5.exponent(str, index, e-1) → 写入指数部分

为什么使用 e-1?

原因:已经放置了一位数字在小数点前
目的:调整指数以保持数值不变
示例:4.55058496E7 表示 4.55058496 × 10^7
4、exponent()分析
标准科学计数法:a.bcd × 10^n
约束条件:1 ≤ a < 10(小数点前只有一位非零数字)

<!---->

private int exponent(byte[] str, int index, int exp) {
    str[index++] = (byte) 'E';  // 写入字符 'E'
    if (exp < 0) {
        str[index++] = (byte) '-';  // 负指数写入 '-'
        exp = -exp;  // 转为正数处理
    }
    if (exp >= 100) {
        str[index++] = (byte) ('0' + exp / 100);  // 百位
        exp %= 100;
    }
    if (exp >= 10) {
        str[index++] = (byte) ('0' + exp / 10);   // 十位
        exp %= 10;
    }
    str[index++] = (byte) ('0' + exp);           // 个位
    return index;
}

输入参数: byte[] str(输出缓冲区)、int index(写入位置)、int exp(指数值)

核心功能: 将指数值格式化为字符串并写入字节数组

处理逻辑: 优化处理1位、2位、3位数的指数

1. 写入 'E'
2. 处理负号(如果 exp < 0)
3. 处理百位(如果 exp >= 100)
4. 处理十位(如果 exp >= 10)
5. 处理个位(必须)

返回值: 更新后的索引位置

例子:

1. 原始数值: 45505849.6
2. 精确指数: 7.658067227112319
3. 调整后指数: 7.658 - 1 = 6.658
4. 四舍五入: 7
5. exponent方法输入: exp = 7
6. 执行步骤:
   - 写入 'E' → index = 1
   - exp = 7 < 10,跳过百位和十位
   - 写入个位 '7' → index = 2
7. 输出: "E7"
8. 完整结果: "4.55058496E7"

根据源代码的逻辑简化了一版如下:

https://coding.jd.com/newJavaEngineerOrientation/Double2Strin...

三、解决方案

3.1 BigDecimal 精准控制

new BigDecimal(doubleValue).setScale(2, RoundingMode.HALF_UP).toPlainString() 

3.2 DecimalFormat 格式化

new DecimalFormat("#0.00").format(doubleValue) // 强制保留两位小数  

四、总结

Double 数值的字符串格式化规则(如 Double.toString())遵循:

•普通格式(Plain):当数值的指数范围在 [-3, 7) 时(即绝对值在 [10^-3, 10^7) 之间),直接显示小数形式(如 0.001 或 123456.0)。

•科学计数法(Scientific):当指数范围超出 [-3, 7)(如 0.000999 或 10000000.0),显示为科学计数法(如 9.99e-4 或 1.0e7)。

作者:高继航

1 前言

2025年,虚拟试衣已成为电商行业不可或缺的核心环节,从技术落地到商业变现,全行业都在加速布局这一赛道。什么是虚拟试衣?其背后的核心技术方案有哪些?国内外电商大厂又有哪些典型实践案例?如何突破技术瓶颈,打造更贴合用户需求的试穿体验?电商平台又该如何构建完整的AIGC能力矩阵?

本文分享将基于京东零售视觉与AIGC部负责人李岩(Jason Li)博士在AICon2025的演讲内容整理呈现,深度拆解虚拟试衣的技术逻辑、行业实践与未来趋势,解锁电商AIGC的全域布局思路。

在这里插入图片描述





内容围绕以下板块展开:首先解析虚拟试穿的定义与分类;其次回顾虚拟试穿的技术发展历程;随后深度拆解行业内主流虚拟试衣产品的核心能力;再介绍京东在虚拟试穿领域的探索及实践沉淀的实践经验;在此基础上,分享京东零售AIGC布局的全景图;最后探讨虚拟试衣及电商AIGC行业的未来发展趋势。

在这里插入图片描述

2 虚拟试穿的定义与分类

在这里插入图片描述

在这里插入图片描述

虚拟试穿的底层逻辑可概括为A+B=AB,其中A指模特的图片或视频,B则是服饰图。通过视觉生成技术将服饰“穿”到模特身上,最终以静态或动态效果呈现给用户,核心要求是保证模特与服饰的关键信息不被破坏、不被篡改。

从不同维度划分,虚拟试穿可分为以下类别:

在这里插入图片描述

首先,从服饰呈现形式来看分类。服饰的素材形态主要有三种:一是平铺的白底服饰图,二是真人模特上身的服饰图,三是假人台模特上身的服饰图。

其次,以服饰数量为划分标准,这一类可以分为单件服饰和多件服饰两类。单件服饰涵盖上装、下装、长款连衣裙以及单件内衣等;多件服饰则是多种单件服饰的组合搭配,这里鞋子、包包、配饰等,也都在虚拟试衣的服务范畴之内。以上就是从服饰的不同维度对虚拟试衣进行的分类。

在这里插入图片描述

接下来,换个角度,从模特的视角来拆解虚拟试衣的分类。

从模特类型来看,可分为全身模特、半身模特、多人模特以及视频模特;

从输出形态来看,则可以分为静态图像模特和动态视频模特两类。

讲到这里大家不难发现,虚拟试衣任务的输入条件其实是相当丰富且复杂的。因此,一个优质的虚拟试穿算法,需要对上述所有的组合矩阵都具备良好的适配能力。而截至目前,要实现这一点,依然存在不小的技术挑战。

2 虚拟试穿的核心价值:三大视角的必要性分析

在这里插入图片描述



虚拟试穿技术的推进源于行业发展、消费者需求与商家痛点三大核心诉求,具体可从三个视角展开:

从行业大环境来看 三年疫情直接推动服饰行业从线下向线上转移。2019年中国服饰线上销售额占整体零售额的25%~30%,2023~2024年这一比例提升至40%,2025年更是突破50%,线上购衣已成为主流消费习惯。

从消费者视角来看 购物的便捷性和私密性需求日益凸显。调研数据显示,65%的女性和54%的男性对传统实体试衣间感到不自在、不方便——狭小空间内的脱衣穿衣操作、冬季厚重衣物的繁琐试穿流程,以及公共区域的疾病交叉感染风险等,均降低了线下试衣体验。而用户天然存在查看服装上身效果的需求,因此AI试穿被视为服饰线上零售在体验上的“最后一公里”。

从商家视角来看 高退货率是服饰电商的核心痛点。这里有一张图,可能经常网购的女生会了解这个梗,现在有不少买家会做“穿完即退”的操作,尤其是礼服类服饰,穿着新衣服拍照打卡、出席活动后,就无理由退货,导致衣服沾染污渍异味,商家根本无法二次销售。为此,商家想出了用“大尺寸+硬质材料”的“巨型吊牌”,来对这种恶意退货进行物理防御。抛开这个梗不谈,普通电商平台的服饰退货率普遍在25%~60%,内容电商直播场景的退货率更高,部分可达80%~90%。商家每处理一件退货,平均需付出15~30元成本,涵盖物流、包装、折旧、仓储及人工处理等环节,跨境电商业务的成本则更高。此外,“穿完即退”等恶意退货行为也加剧了商家损失,因此行业亟需稳定、可靠的线上试穿技术与产品能力解决上述问题。

3 虚拟试穿的行业核心难点:用户预期的三层进阶需求

在这里插入图片描述

虚拟试穿到底好不好做,行业的核心难点又在哪里?聚焦C端场景,虚拟试穿的核心难点集中在用户对技术的三层进阶预期,各层次需求对应的挑战各不相同:

第一层是基础型需求,核心是服装上身效果的精准还原,包括颜色、款式、版型和面料质感。这一层面的难点主要有四:一是用户相册中往往缺乏直接可用的素材,尤其男性用户,难以提供合格的全身或头肩部位肖像;二是试衣算法需保证模特脸部等关键信息不被篡改,尤其是脸部特征,试穿前是什么样子,试穿后核心的面部ID信息必须保持一致,试穿前后核心面部ID信息保持一致;三是真实还原与美学增强的平衡“矛盾体”——算法初期优先追求信息还原,但女性用户对美观度诉求强烈,部分用户可接受轻微肖像修改以提升效果;四是试衣模型多基于扩散模型搭建,试穿效果依赖模型储备的世界知识。

第二层是尺码合身需求,这是大众认知里,虚拟试穿最核心的刚需,也是目前实现难度最高的需求,行业内尚无成熟技术方案。从算法层面看,核心瓶颈是尺码错配训练数据的极度匮乏——电商平台买家秀多为合身尺码展示,缺乏“小体型穿大码”“大体型穿小码”等这类尺码mismatch的完整数据;此外,大量长尾服饰本身存在尺码信息缺失问题,不同品牌、品类的尺码标准不统一,这也是为什么有些店家会建议用户拍大一码或拍小一码。并且,用户对尺码存在个性化偏好,有人偏爱宽松的大码版型,有人则更倾向于合身的小码版型。所以说,尺码合身这个需求,是目前虚拟试穿技术实现中最大的难题,这进一步提升了实现难度。

第三层是突破型需求,即基于用户身材与具体场景的智能穿搭推荐及个性化风格探索。这一层,用户的典型诉求是基于自身身材与具体场景,获得智能穿搭建议,甚至进行个性化的风格探索。比如:用户可以输入自身情况,提出“要参加朋友婚礼该怎么穿搭”“出席孩子家长会适合穿什么”这类场景化需求;也可以针对已有单品提问,比如“我有一件这个颜色的上衣,搭什么下装最合适”“这条裙子配哪种外套更好看”。这些都是用户在穿搭推荐上的典型诉求。这一需求的实现难点在于:一是模型必需精准理解用户的身材特征,避免推荐不符合体型的服饰,比如不能给体型偏胖的用户推荐短款显壮的衣服;二是做好用户历史偏好建模,准确捕捉用户过往的服饰品味,让推荐更贴合其个人喜好,不能给穿衣风格偏保守的用户推荐过多潮流品牌;三是需要获取并理解“时空人”信息,就像现在12月的北京已经入冬,天气寒冷,推荐时就应该优先考虑羽绒服这类御寒衣物。最后,既然要做风格探索,就必须持续投入穿搭知识库的构建,同时积极追踪最新的时尚潮流,这样才能给用户提供前沿且合适的穿搭建议。

4 虚拟试穿的技术发展历程:从学术起源到行业主流

在这里插入图片描述

4.1 学术起源与框架演进

在这里插入图片描述

虚拟试穿的技术发展历程是什么?从虚拟试穿技术的发展看京东零售技术实践和未来发展方向。

通过文献梳理可以发现虚拟试穿(Virtual Try On)的学术概念最早于2001年由日内瓦大学研究人员正式提出,这样早期研究给出了网络环境下基于人体克隆的服装试穿解决方案。采用高度定制化技术,需从特定角度对人体拍照取样,依赖流程化、模块化操作及关键节点定位技术,这就是虚拟试穿技术的学术开端。

在这里插入图片描述

2001年至2025年的二十余年间,虚拟试穿技术在学术界的框架演进可分为三个核心阶段:

第一阶段2001年至2013年,主流方案以3D建模、物理仿真及AR(增强现实)技术为核心;

第二阶段2017年至2022年,技术路径转向基于CNN与生成对抗网络(GAN)的框架;

第三阶段2023年起,扩散模型(Diffusion Model)异军突起,此后绝大多数研究都聚焦于这一技术方向,直到现在扩散模型依然是虚拟试穿领域的最主流技术方案。

在这里插入图片描述

与此同时,虚拟试穿技术在学术界“绕不开”的四类核心研究文献可归纳为四类:第一类是生成对抗网络(GAN)方向,相关研究主要集中在2017到2022年,核心都是基于GAN技术来实现虚拟试穿。第二类是扩散模型方向,正如之前提到的,2023年之后这类研究开始爆发,不同的网络结构和试穿任务场景,都能在这个方向找到具有行业影响力的论文。

在这里插入图片描述

另外两类分别是视频试穿方向和套装试穿方向。随着单件服饰图像试穿技术逐渐成熟,学术界开始朝着不同维度拓展研究边界,一个是从静态图像延伸到动态视频,一个则是从单件服饰试穿升级到多件搭配的套装试穿。



4.2 京东零售虚拟试穿技术的四代演进

在这里插入图片描述



而京东零售自2023年启动虚拟试穿项目研发,至今已有两年多的积累,期间历经了四代大的技术框架迭代,积累了丰富实践经验:

第一代是非常早期的架构,以U-Net作为扩散模型主体,搭配Reference Net来实现参考服饰的信息注入。这个框架大家应该比较熟悉,属于Stable Diffusion时代的产物,它的扩散模型参数规模不算大,对应的图像生成效果也相对有限。

在这里插入图片描述



第二代技术框架将扩散模型主体结构从U-Net升级为DiT,服饰信息特征表示借助ViT与VAE完成,与2024年行业技术趋势同步(Sora的出现推动行业普遍完成U-Net到DiT的切换)。这次升级其实和行业趋势同步,2024年年初Sora横空出世,让大家看到了DiT作为扩散模型框架的先进性,因此大部分行业机构都在2024年上半年完成了从U-Net到DiT的技术切换。基于第二代技术框架的实践,我们也沉淀了三个比较重要的认知分享给大家。第一,基座模型的架构和容量对试穿效果起到决定性作用。这一点也印证了扩散模型的Scaling Law,从最初的1B模型,到3B、10B、20B,再到融入VL框架后升级至30B乃至更大参数规模,模型的生成效果有着肉眼可见的提升。第二,利用VAE对参考图像进行编码,能极大提升生成结果的一致性。ViT的表征更偏语义层面,而VAE的训练以重构残差最小为优化目标,更擅长捕捉图像细节。在实际试穿中,若遇到衣服logo等细节还原不佳的问题,往往就是因为没有正确使用VAE编码器来做服饰特征表征。第三,在这套框架的试穿任务中,无需对参考图进行prompt描述,如强行加入文本描述,反而很可能引发图文冲突与对抗。不过这个结论并非绝对,要结合具体技术框架来看,在当前的DiT+ViT+VAE框架下,我们是可以剥离文本模块的,但后续融入VL模型表征后,文本侧的信息也能发挥相应的价值。


在这里插入图片描述

京东零售的第三代虚拟试穿技术,核心完成了从图像试穿到视频试穿的模态升级。目前行业内的视频生成框架尚未形成统一标准,我们可以分享一套可供参考的技术方案:首先将原始视频解析为带mask的视频帧序列,以及类似OpenPose的“火柴棍”姿态帧序列;再分别对这两类序列进行编码、建模、,最终通过MM-DiT完成去噪,生成服饰上身的视频试穿效果。

在这里插入图片描述

而京东零售最新的第四代虚拟试穿技术,这一代框架最显著的变化,就是完全摒弃了Mask模块,全面拥抱Mask Free的通用技术架构。与此同时,参考图的表征方式也从原来的纯视觉维度,进化为融合文本模态的多模态统一表征,这里我们引入了Vision Language Model 视觉语言模型来专门完成参考图的特征提取。基于第四代框架的实践,我们也沉淀了几个关键认知:第一,Mask Free框架对人物的身份特征、肢体姿态、服饰细节以及配饰元素,都能实现更好的保留效果;第二,该框架彻底摆脱了Mask模块可能带来的误差累积,同时大幅降低了工程研发的复杂度。毕竟从研发角度来说,系统模块越简洁,引入连带问题的概率就越低,而Mask模块本身会因不同应用场景产生各种badcase,容易引发新问题;第三,Mask Free框架可以更好地兼容套装试穿,以及服装与配饰的同步试穿需求。举个简单的例子:在传统Mask方案中,需要先mask掉用户原有的衣物,再叠加新服饰,可如果用户原本还斜挎着小包,这个包包大概率会随旧衣被mask掉,相当于破坏了用户的原始信息,而通过Mask Free的技术框架,就能实现“新衣上身,配饰保留”的效果。

4.3 技术小结与核心观点

在这里插入图片描述



结合虚拟试穿技术发展历程和京东零售的技术实践,给正在做或将要做虚拟试穿的企业或相关产研人员建议,可总结以下核心观点:

一是启动项目前一定要拿到最好的图像生成基座模型,因为模型的世界知识和基础能力,直接决定了整个项目的起跑线。请大家始终相信Scaling Law,至少在30B参数规模以内,这种效应的验证效果是非常清晰的。

二是Mask Free技术框架会成为未来的主流方向,大道至简,越简洁的技术路线越正确,如果现在还有同学在Mask based方案里摸索,建议果断舍弃那些冗余的模块,尽快拥抱Mask Free的通用技术框架。

三是从单件试穿到多件试穿是必然的技术趋势,而且必须要兼顾配饰。在我们看来,“试穿+穿搭”才是更具想象力的产品形态。我们现在聊的更多是“穿”的环节,但从产品层面来说,更关键的其实是“搭”的能力。

四是试穿结果的视频化,是用户的核心诉求,这一点毋庸置疑。毕竟线下试衣时,大家都会对着镜子转身、摆动,动态效果才更贴近真实体验。但这需要我们长期攻克推理效率的难题,目前生成一段10秒的试穿视频,耗时基本还是分钟级,这样的速度对线上用户体验的影响是比较大的。

五是数据的价值,用于试穿的训练数据,会成为各大电商平台的核心资产。极致的试穿效果,主要依赖于企业的in-house数据。我们都知道,数据是大模型的核心,虽然有些从业者为了凸显技术深度,会刻意回避甚至弱化数据的重要性,但事实就是如此。尤其是虚拟试穿这类赛道,每个企业都会建立自己的数据壁垒。同时,随着AIGC能力的提升,模型训练早期可以借助AIGC数据快速收敛到任务需求,后续再用真实数据校正,就能有效规避AIGC生成内容带来的失真。



5 虚拟试穿的行业实践方案:国内外典型案例解析

在这里插入图片描述



而在虚拟试穿的行业实践方案,目前国内外电商大厂已推出多款虚拟试穿产品,覆盖C端购物场景与B端商家服务场景,各产品特点与局限性各有不同:

在这里插入图片描述



首先来看整个行业的发展概况,这里有三组关键数据分享。

第一组数据是200亿美元,2025年全球虚拟试穿平台的市场规模预计将突破200亿美元,这其中涵盖图像生成、增强现实(AR)以及3D虚拟试衣等多个细分技术方向,而中国市场的规模,预计将占到其中的50亿美元左右。

第二组数据是60余个品牌,截至今年12月,国内已有超过60家服装品牌对外宣称具备虚拟试穿能力,覆盖快时尚、运动等多个品类,这些品牌的核心分布区域,也集中在欧美中日韩等时尚消费的核心地带,像Zara、Nike、Gap、H\&M,以及中国的李宁、安踏等,都在其列。

第三组数据是60%,有机构预测,到2026年,全球将有超60%的服装品牌采用不同形式的虚拟试穿解决方案,届时,这项技术将从当前的“可选配置”,正式升级为整个行业的“标配能力”。

上方是目前国内外在虚拟试穿领域具备技术储备的部分机构和企业,供大家参考。

5.1 国内C端购物场景案例分析

逐个拆解虚拟试穿行业里几家互联网大厂的典型实践方案。


在这里插入图片描述

阿里Lookie: 它是一款主打虚拟形象搭配试穿的AI娱乐工具。

这款产品的核心特点有两个:一是玩法丰富、搭配自由度高,而且自带很强的分享属性;二是“电子衣橱”的概念很有新意,精准命中了用户多件服饰试穿搭配的潜在需求。

当然,我们也客观地分析一下它当前存在的局限性。第一,Lookie目前仅支持套装试穿,不支持单件试穿。套装试穿在娱乐场景下确实很有吸引力,但电商平台的用户购买行为更多集中在单件服饰,这就形成了一个明显的场景缺口。第二,它作为淘宝的一款中心化小程序,入口相对较深,导致产品的购物属性偏弱。如何从“好玩”迭代到“好用”,最终实现商业变现,是Lookie团队需要重点回答的问题。第三,从试穿效果来看,生成的形象和用户真实身材仍存在一定差异,大家可以去淘宝小程序里亲自体验感受。第四,Lookie的人物形象建模,在一定程度上依赖于LoRA数字分身技术。熟悉这个技术的人应该知道,早期的妙鸭也是这样,需要用户上传十几张个人照片,付费后等待模型训练,才能生成专属数字分身,后续试穿也都基于这个数字分身来完成。但这种技术方案对训练资源的要求较高,算不上是行业内ROI最优的选择。不过值得一提的是,Lookie目前已经开始尝试支持单张图像建模,在降低用户使用门槛上往前又迈出了一步。

在这里插入图片描述



淘宝AI试穿: 它是一款入口布局激进、功能设计清爽的购物助手。

这款产品的核心特点有两个:第一,它的入口直接设置在搜索双列的商卡上,这个位置的选择相当大胆激进,能最大程度触达购物链路中的用户;第二,它的推理速度较快,试穿效果稳定,产品功能也足够聚焦,整体使用体验十分清爽。

当然,它也存在两处明显的局限性:其一,目前淘宝AI试穿仅支持上传用户相册里的全身正面站立照,这个要求对不少用户来说存在使用门槛,而且产品缺乏虚拟形象定制能力,毕竟从相册里找出完全符合要求的照片,并不是一件容易的事。而虚拟形象定制恰恰是降低使用门槛的有效方式。其二,它现阶段只具备单品试穿能力,没有搭载穿搭推荐功能。我们之前提到过,穿搭是试穿场景中非常重要的延展环节。不难发现,阿里的这两款试穿产品在一定程度上形成了互补:淘宝AI试穿专注于单件试穿场景,深度嵌入核心购物链路;而它所欠缺的穿搭能力,正好可以由Lookie小程序来补齐。



5.2 海外C端购物场景案例分析

介绍完国内电商平台的试穿产品,我们再把目光转向海外,看看海外的虚拟试穿技术能力。


在这里插入图片描述



Google Shopping Try On: 这是一款主打高真实性的购物决策工具。

它的核心特点有三个:第一,具备跨端覆盖的试穿能力,同时支持移动端与桌面端,能满足不同用户的使用习惯;第二,服饰覆盖率极高,几乎涵盖了Google Shopping平台上的全量服饰品类;第三,支持用户上传个人照片或使用AI模特,而且对用户上传素材的包容度很高,要知道,通常模特姿态越简单,试穿效果越容易把控,但Google Shopping Try On即便是面对坐姿、非标准站立等有难度的姿态,也能处理得比较好。

当然,它也存在明显的局限性,这点和淘宝AI试穿有些类似,即仅支持单品试穿,暂未开放穿搭组合的试穿功能。

5.3 C端内容电商服务场景案例分析

介绍完货架电商场景下的典型AI试穿能力,我们再把目光转向内容电商,这里以抖音的AI试穿为例来分析。

在这里插入图片描述



抖音AI试穿: 是一款主打“直播+试穿”的新体验产品。

它的核心特点有三个:第一,与直播场景紧密结合,用户从看到商品到完成试穿的链路快捷又易用;第二,同时支持上传用户真实照片和使用AI模特,在一定程度上降低了用户的使用门槛;第三,除了当前入口的商品,还能支持同店铺内的穿搭推荐,正好契合了我们之前提到的试穿延展需求。

这款产品也存在两处局限性:其一,虽然配备了AI模特,但这些模特的肖像和用户本人没有关联,更像是一张“平均脸”,用户会觉得是陌生人在试穿,而非自己,体验上会有割裂感;其二,它的其中一个试穿入口设置在商品详情页的尺码助手附近,而目前行业内并没有成熟的技术能支持尺码合身效果的试穿,这就容易给用户造成误导,用户本以为点进来能看尺码是否合适,实际却只能看到服饰上身的基础效果,从产品入口设计的角度来看,还有进一步优化的空间。

5.4 B端商家服务场景案例分析

介绍完面向C端的虚拟试穿产品方案,接下来看一个B端的典型案例。

在这里插入图片描述

阿里绘蛙: 这是一个专门服务服饰电商商家的AI内容生成平台。

核心特点有三个:第一,自带海量素材库,涵盖参考图与模特素材,为商家提供了充足的选择空间;第二,同时支持单件与多件服饰上身生成,而且输出素材的分辨率较高,清晰度能满足电商展示、内容种草等多类场景的需求;第三,试穿功能可与平台内其他AI工具无缝联动,比如用试穿能力生成效果图后,能直接在平台内调用图像编辑功能进行二次优化,操作流程十分顺畅。

当然,绘蛙也存在一些局限性:一方面,作为B端生成式服务平台,它目前的生产效率相对偏低,推理耗时基本是分钟级,暂不支持大量素材的批量生成,这对于有规模化生产需求的商家来说是个不小的遗憾;另一方面,受B端的产品定位所限,平台缺少C端用户的使用场景,毕竟普通消费者更习惯在手机购物链路中使用试穿功能,而绘蛙的核心用户群体始终是电商商家,主要用于制作商品相关素材。

5.5 行业分析小结

在这里插入图片描述

结合上述案例,可总结行业实践核心要点,从四方面展开:

第一,B端与C端的定位分化清晰,PC端或Web端聚焦服务B端商家,提供模特生成、AI试穿、素材二次编辑等能力,批量化、低成本生产是商家的核心诉求。如果平台能打通“素材生产—投放—效果验证”的闭环,并将验证结果反馈给模型辅助进化,会成为中小商家的一大福音。而APP端或小程序端则瞄准C端用户,主打简化操作流程,联动购物闭环以适配移动端的碎片化体验;再次强调,对于C端而言,“穿”是刚需,但“搭”才蕴藏着更多产品机会。

第二,入口形态决定产品定位。电商平台的AI试穿入口无非两种:第一种是非中心化入口,将试穿能力嵌入购物全流程,比如直接放在每个商品的商卡上,实现“见品即试穿”,核心目标是强化用户的及时决策;第二种是中心化入口,类似阿里Lookie的小程序单入口,不依附于具体sku,能打造独立场景,延伸穿搭推荐、社交分享等功能,让产品从购物工具升级为内容娱乐的社交载体。

第三,通过多元方案降低用户使用门槛。针对用户相册难以找到合格全身照的痛点,行业内普遍采用多种路径打破传图依赖:一是虚拟捏人;二是非标图像兼容,提升算法能力,支持半身照等非标准素材试穿,比如用半身照试穿上衣;三是“大头照+身材参数”实现数字形象,以此降低C端用户的试穿启动门槛,这些都是值得肯定的产品尝试。

第四,尺码破局需要技术与策略双重保障。单纯依靠算法模型,很难解决尺码合身的试穿问题。行业的可行思路是联动尺码助手、用户试穿报告等策略工具,用“技术生成效果+策略辅助决策”的双重模式降低用户购物决策风险,最终实现退货率的下降。



6 京东的虚拟试穿实践:产品特点与核心经验

在这里插入图片描述

6.1 京东虚拟试穿产品现状

在这里插入图片描述

京东零售虚拟试穿产品目前处于小流量测试阶段,产品主要有四大特点:精准的身材识别、逼真的材质渲染、高效快速的生成、智能的搭配推荐,这也是京东零售虚拟试穿一直持续打磨的产品目标。现阶段产品已覆盖超百万服饰SKU,实验阶段用户量突破100万,覆盖70多个服饰类目,合作头部服饰品牌超500家。

在这里插入图片描述

从具体功能来看,产品设计包括三大核心模块:

一是最左侧图示,商详主图的试穿入口,目前这个入口的设置比较保守,没有像淘宝AI试穿那样直接嵌入搜推双列商卡,我们认为在实验阶段,还是尽量避免影响用户原有的购物体验,后续会根据测试效果考虑提升入口优先级。

二是中间三张图示,我们重点探索的同款不同色服装试穿,用户从某一款颜色的服饰(比如图中的粉色羽绒服)进入试穿页面后,可以一键切换同SPU下的白色、黑色等其他配色,便捷完成多色试穿对比。

三是最右侧图示,我们正在积极推进的上下装搭配试穿,系统会为入口服饰,比如这件羽绒服,匹配同店铺内的裤子、裙子等下装,让用户直观感受不同搭配的视觉效果。当前我们把搭配候选池限定在同店铺内,从消费者视角来看,打破店铺限制可能会更有吸引力。从技术层面来讲,跨店铺搭配的实现难度也并不大,核心在于业务逻辑的梳理,这需要我们与商家做更深入的调研沟通,明确背后的商业价值后,再考虑进一步的功能升级。

6.2 京东虚拟试穿产品实践经验

在这里插入图片描述



京东在虚拟试穿项目实践中沉淀下来的三点核心经验:

一是需全力降低用户使用门槛——我们有一组数据可以佐证这个观点,目前线上使用虚拟试穿的用户中,超过半数无法上传符合要求的试穿照片。即便我们在上传页面做了详细的规则引导,用户从相册里找到合规照片的难度依然很高。为此,我们果断加入了数字人模式,采用“真实照片上传+虚拟数字人形象”的双轨方案,用户如果找不到合适的照片,或者不愿上传个人照片,就可以输入身高、体重等参数打造专属数字人;若能提供肖像照,数字人会更贴近用户本人,没有肖像照也可以使用默认形象,这是降低用户使用门槛非常行之有效的方法。

二是穿搭场景中,“搭”大于“穿”。正如之前提到的,“穿”是用户的基础性刚需,而“搭”属于突破性需求。但在电商场景下,用户对穿搭的期待其实很高,所以我们一直在积极探索为用户提供多样化的搭配可能性,以此挖掘更多产品价值。

三是试穿效果要兼顾“像”与“美”,二者缺一不可。这一点往往被很多项目组忽略。用户对试穿效果的核心要求是“真、像、美”:“真”是衣服和人物的真实感,不能有明显的AI痕迹;“像”是人物ID、服饰细节、环境背景的精准保留;而“美”常常被忽视,但其实至关重要。我们在算法侧也把评测标准,从最开始的“衣服还原不出错”,升级为“可用率+美观度”的多维度评估体系。这里可以举个例子:大家做虚拟试穿,都是希望提升转化率、降低退货率,但如果忽略了“美”的需求,很可能连转化率都会受影响。没有试穿时,用户看商详主图觉得衣服不错就会下单,但AI试穿后发现效果不好看,反而会直接放弃购买。这其实是大模型在落地原生AI场景时会遇到的阵痛,所以我也呼吁行业同仁,面对这类问题要保持长期心态,用户心智的培养和行业的迭代,都需要一个过程

6.3 京东虚拟试穿未来探索方向

在这里插入图片描述



结合行业趋势、实践经验与用户需求我们认为未来值得探索的虚拟试穿产品形态,以下三类产品形态具有较高探索价值:

第一个是万物成套的试穿试戴系统,服饰试穿已经从单件升级到多件,但对于注重OOTD的用户来说,鞋子、配饰、包包甚至手机壳,都是穿搭的重要组成部分。我们希望未来能实现全品类的组合式穿搭,打造真正的“万物穿搭”试穿效果。

第二个是数字人虚拟试穿+AI导购,想象一下,每个用户都有专属的数字人形象,它既可以是你的分身,也可以是你的AI导购助手。你在逛商品流的时候,轻触商卡就能把衣服“穿”到数字人身上,同时还能和这个数字人对话,让它帮你推荐搭配,实现7×24小时的购物陪伴。这其实也是电商2.0时代追求的极致沉浸式个性化体验,我们甚至畅想过一个更极端的场景:用户浏览服饰商卡时,卡面展示的就是自己穿着这件衣服的形象,滑一屏都是专属的上身效果,选款会更直观。不过这种形态需要充分尊重用户意愿,避免造成冒犯,同时也面临着推理资源、生成效率等工程侧的巨大挑战。

第三个是电子衣橱。这个概念虽然已有部分产品提及,但我们认为还有很大的深挖空间。用户可以把已购、收藏的服饰都放进这个虚拟衣橱,系统根据天气、出席场合等场景,为用户提供交互式、陪伴式的试穿搭配建议,真正实现“衣随场景搭”。

7 从虚拟试穿到全域布局:京东电商AIGC能力矩阵

在这里插入图片描述

7.1 京东电商AIGC能力矩阵

从虚拟试衣切入,到更大范畴的电商AIGC。京东零售在电商AIGC领域的能力布局,整体可以分为八大能力板块,全面覆盖商品素材制作、营销推广、用户体验等关键环节。

在这里插入图片描述

第一,商品智能抠图。这是所有电商平台最关键、最基础的技术能力,抠图效果的优劣,直接影响后续整条素材制作链路的最终呈现质量。第二,商品素材生成。我们依托AIGC技术,实现主图、商详图、广告素材的自动化生成。在技术加持下,内容制作周期大幅缩短,素材迭代效率提升了数十倍。第三,视频生成。从2024年开始,视频生成技术的效果已经被大家广泛认可,国内相关技术也实现了大幅跃升。我们主要聚焦主图视频和营销视频两大场景:主图视频时长较短、镜头单一,主打快速展示商品核心卖点;营销视频则篇幅更长、内容更丰富,通常会搭配剧本与口播,用于深度种草和品牌宣传。第四,AI模特。这项能力不仅服务于服饰场景,也覆盖了众多非服饰品类的素材生成需求。传统模式下,头部商家会邀请明星代言,中型商家则需要对接外部服务商拍摄,不仅成本高昂,还会拖慢商品上新节奏。而AI模特能力通过AIGC技术,为商家快速生成适配不同场景、不同风格的模特素材,有效降本增效。

在这里插入图片描述

第五,虚拟试穿。这项能力不过多赘述了,今天的分享主题基本都围绕它展开,核心是通过AIGC技术实现服饰的虚拟上身与搭配,降低用户决策成本。第六,AI设计家。也可以称之为“放我家”功能,主要服务于家具等大件商品场景。用户上传自家房屋照片后,AI就能将目标家具植入到真实家居环境中,直观呈现摆放效果;同时还能针对毛坯房、清水房,按照用户需求设计出对应的装修风格,解决家居选购与装修设计的可视化难题。第七,3D立影。这是京东零售自研的AIGC裸眼3D技术,能让商品从商卡中“跳脱”出来,以3D形态呈现。这项技术能显著提升品牌商品的点击率,以及直播场景下的用户互动率。第八,数字人。相信大家对京东数字人并不陌生,目前已有超2万个品牌在使用这项能力,相关场景的转化率提升了30%。它最直接的价值是实现7×24小时数字人直播卖货,打破传统直播的时间限制,持续为商家创造收益。

7.2 京东电商AIGC实践案例

接下来,选取其中几项能力,展开分享京东零售在业务侧取得的实际成果。

在这里插入图片描述

第一个是商品素材AIGC生成。这里展示的是一款起泡酒的案例,覆盖商品主图、商详图、卖点图和广告图等全类型素材。目前这项能力已经改变了京东超100万商家的内容设计模式,既大幅提升了素材制作效率,又显著降低了制作成本。


在这里插入图片描述



第二个是AI模特。模特图生成技术正逐步在头部品牌中批量落地,我们过去已与Nike、阿迪达斯、海澜之家三大时尚品牌达成深度合作。在批量应用阶段,合作品牌的商品转化率提升29%,商品上架速度提升90%,同时商品素材制作成本大幅下降。大家现在在这些品牌店铺里看到的部分模特图,正是由我们的AIGC技术生成,再结合虚拟试穿能力完成服饰上身的。


在这里插入图片描述



第三个是AIGC裸眼3D技术,立影。这里有SK-II和华为耳机两组合作案例,这项技术能明显带动品牌点击率与销售转化率的提升。目前它主要应用于广告投放、家具搭配、直播互动、互动游戏以及试装试戴等场景。

7.3 京东电商AIGC设计智能体:焕新版京点点Oxygen Vision

在这里插入图片描述



京东零售电商AIGC内容生成平台“京点点”整合了上述大部分能力,目前已支持超过30种业务场景(覆盖商品发品、运营、营销等环节),日能力调用量超1000万次,服务超100万京东商家,助力商家内容生产成本降低90%,生产效率提升95%。

在这里插入图片描述



近期,京点点平台完成系统性升级,焕新版命名为Oxygen Vision平台。新版平台和老版最大的差别,一方面是集成了更多的AIGC能力项,另一方面则是把交互形式从原来的纯GUI交互,升级为Linguistic UI + GUI的混合模式。

具体来说,新版平台具备四大核心特点:第一,对话式人机交互,支持纯自然语言的交互方式,操作更便捷;第二,大模型驱动的任务规划与执行,能够拟人式地分步骤、有序完成各项操作;第三,强一致性且不失多样性的商品素材生成能力,确保生成内容既贴合商品属性,又能满足多样化需求;第四,无缝接入京东AB实验平台的能力。正如我们之前所说,一个合格的B端AIGC内容生成平台,必须打通“素材生产—投放—实验回收—模型迭代”的完整闭环,而这一点,新版京点点平台已经完全具备。

在这里插入图片描述



8 电商AIGC的未来展望:技术纵深与商业价值

在这里插入图片描述



8.1 AIGC应用的三层分类与技术复杂度

在这里插入图片描述

最后未来展望,来看电商AIGC的技术纵深与商业价值,分享个人观点和思考。

首先,从上图来看,AIGC的应用分成了三个层次。最底层的是创意类应用,这类应用的自由度高、约束少,核心是满足用户的个性化表达需求,比如短视频平台的魔法表情特效,运营活动需要的banner海报、插画设计,都属于这个范畴。往上一层是影视类应用。如果大家了解即梦、可灵、海螺这些视频生成工具,应该会有体感,这类应用的核心是通过AIGC实现角色和场景的一致性保持,技术难点也集中在这里。不过说实话,普通消费者对于这类内容的细节一致性,敏感度其实没那么高。而最上层的,就是我们今天一直在聊的电商类AIGC,这个方向,需要解决海量SKU的适配问题,要确保商品信息的准确传递,还要满足实时转化的业务诉求,同时还要应对严格的合规风险。

如果从技术复杂度排序,创意类最简单,影视类次之,电商类堪称地狱级难度。为什么这么说?因为电商AIGC对商品一致性的要求是极致严苛的,哪怕是一个细节的偏差,比如裙子本该没有花边,生成的素材里却加了花边,用户收到货发现“货不对版”,就可能引发客诉,甚至是官司。这和影视类的一致性要求完全不是一个量级,更别说创意类的开放创作模式了。但有意思的是,这三类应用里,电商类AIGC恰恰是距离商业化、距离“钱”最近的。做了这么久的AIGC应用,有一个很直观的体感:有两类应用场景是可以直接实现变现的。第一类,就是影视类AIGC。这个很好理解,举个例子,拍摄《速度与激情》时,要呈现兰博基尼和法拉利相撞的画面,在没有AIGC技术之前,这样一个镜头的成本可能高达上百万;而现在,依托可灵、即梦这类视频生成工具,成本有可能直接降到几百美金。无论是文本生成视频、图像生成视频,还是首尾帧驱动的视频生成技术,都能支撑这类特效镜头的制作。更值得一提的是,现在很多视频生成能力还叠加了音画直出功能,这让电影级别的多媒体内容高效输出,变得越来越有可能。第二类,就是电商与商业化AIGC。这里我们暂时不做细致区分,核心逻辑很简单:我们用AIGC生成的电商素材,是直接供商家用于商品运营和投放的,最终指向的就是GMV的增长,这是最直接的收益。商业化场景也是同理,通过AIGC制作广告素材,直接面向广告主和用户,素材投放后带来的广告消耗,直接对应着平台的营收。所以在我看来,电商与商业化AIGC,是现阶段离“钱”最近的应用方向。这就是个人对整个AIGC行业应用落地的一些理解。

8.2 未来展望

在这里插入图片描述

最后,再分享三个总结性的观点。

第一,从技术角度来看,像虚拟试穿这类垂直业务,未来不会再依赖专属定制模型。一个明确的技术趋势是,越来越多的电商AIGC任务,会统一到通用大模型框架之下,就像nano banana pro这类架构一样,用户只需要在prompt层面定义好业务需求,就能完成相应任务。只不过现在还有不少虚拟试穿方案,还停留在定制化思路上,这个转变需要一个过程。

第二,想和所有AIGC创业者、以及大厂里做AI提效的同学聊一句:不是所有业务都需要升级到LUI(对话式交互)的形式。有些功能用GUI(图形界面)来承载,体验反而会更好。不要觉得套上LUI的壳,就是做了AI native的升级,很多时候这种做法反而属于“故弄玄虚”。这两年大家应该也见过不少“AI小助手”“智能XX工具”,本质上就是把原来的GUI功能强行改成对话式,看似用上了大模型和Agent,实际体验反而不如从前。尤其是编辑类需求,图形化的交互方式往往更直接高效。而新京点点平台之所以选择LUI+GUI的混合模式,核心是看服务对象,我们主要服务的是京东的采销同学。他们每个人负责的SKU数量极多,不可能针对每个商品去定制化制作素材,更需要“一句话指令”就能自动生成内容的傻瓜式操作。这样才能让采销把精力聚焦在拿货、议价、仓储运营这些核心工作上,而不是耗费在素材制作上。

第三,关于电商2.0核心方向,极致的沉浸式与个性化购物体验是核心目标。虚拟试穿是沉浸式体验的重要探索,而个性化购物的底层支撑是“千人千面”的商品素材生成能力。这也是京东在探索大模型时代电商2.0形态的一条核心技术路线。大家对“千人千面”并不陌生,过去京东零售的搜索推荐就是如此,同样搜索一个关键词,不同用户看到的结果页截然不同。但到了商品素材层面,目前商品素材仍处于“千人一面”状态,商家只维护了一套主图、商详图和卖点介绍。而“千人千面”的商品素材生成,就是要打破这种单一性。比如:一款中性款冲锋衣,面对三类不同需求的买家,可以用算法提炼出他们各自关注的核心卖点,定制差异化的素材,既精准吸引用户,又提升购物体验。第一类是户外功能型买家,他们最关心面料科技、防风防水、透气耐磨这些专业指标,AI就在商品图上重点呈现这些性能参数;第二类是外观穿搭型买家,他们不纠结材质,只在意设计风格、版型潮流和穿搭适配,AI就主打OOTD相关的素材生成,突出颜值和搭配感;第三类是价格敏感型买家,他们不关注功能和颜值,只看价格、优惠和赠品,AI就直接在图片贴片上展示最低价标识、优惠券、赠品信息等内容,实现精准引流与体验提升。通过这个案例,大家应该能更直观地理解什么是“千人千面”的商品素材能力。当然这个话题还有很多细节可以展开,可点击查看《从 “千人千面” 的搜索推荐到 “千人千面” 的商品素材技术探索》文章,里面有更详尽的介绍。

本问答帖原创发布在华为开发者联盟社区 ,欢迎开发者前往论坛提问交流。

 

使用 arkweb 的 onTitleReceive 获取 web 的 title 有时候并不是和 document.title 是一致的,而且 onTitleReceive 经常会返回 url 字符串,请问这种问题应该如何应对?

解决方案:

· 方案一:在onTitleReceive中通过 webController.getTitle()获取网页的标题。

· 方案二:通过runJavaScript执行 JavaScript 代码来获取文档的标题。如果 getTitle 返回的是网页 url,那是因为当前网页未设置 title。正常来说通过 webController.getTitle()获取到的网页标题和 document.title 是一致,如果遇到不一致的情况,可以自由选择方式一或者二。

具体参考 demo/操作步骤,请点击原帖查看:

Arkweb如何正确加载web的当前title?-华为开发者问答 |华为开发者联盟 (huawei.com)