所有文章
安全摄像头的Webhooks和HTTP Push功能
本文介绍了部分安全摄像头产品中所支持的WebHooks和HTTP Push的第三方报警平台的功能,以及该功能实现的架构与通信流程最佳实践。 摄像头Webhooks和HTTP Push告警功能 常规的摄像头,在通过 PIR 或者 AI(如人形检测、人脸识别、车牌识别)等方式检测到事件后,可以把这个事件的消息以及录像视频推送到自己的云平台,并由自己的云平台转发到用户的手机 APP 上。所有的事件推送流程以及与之相关的事件录像文件都局限于摄像头厂商的封闭生态之中。 相比于以上这种传统的只绑定自家 APP 的封闭生态,通过 Webhook 或者 HTTP Push 的功能对外推送事件通知,意味着这个摄像头设备可以直接接入第三方中控系统或安保报警平台。 _实际上,Webhook 本身并不是什么高深的新协议或新技术,它的底层逻辑实际上就是:__当特定事件发生的时候,系统会自动向预先配置好的 HTTP Server 发送一条 HTTP 请求(通常是 POST)来告知事件信息而已。所以在某些系统的配置中,这个功能也被称之为HTTP PUSH、Alarm Upload。_ !6f83a518-7eb6-4b00-b356-b3cf0b863d8f.png 实际上,绝大部分面向企业级(B2B/SMB)和高端商用的品牌(如海康,大华,Axis,Meraki)都原生支持 Webhook/HTTP 请求推送,而面向纯C端消费级(B2C)的品牌(如Ring,Arlo,Nest,Eufy,Wyze)大多倾向于建立封闭生态,不原生开放 Webhook,这样可以把用户锁定在自己的 App 生态内,并推广自己的云存储订阅服务。 以下是一个典型的安全摄像头系统的 Webhooks 的配置界面: !c00a0634-a6f1-481c-af0e-44f589234235.png WebHook实现的两种架构方案 针对 WebHook 或者 HTTP Push 的具体实现,主要有端侧直推和云端转发两种技术方案,分别针对于不同的应用场景。 端侧直推 以下为端侧直推方案的架构:第三方告警服务器的 URL 直接设置到摄像头端,由摄像头内部的固件直接发起 HTTP POST 请求,通过自己的网络将数据直接推给第三方 URL。 !ca544108-6ceb-4f9b-8640-225d345f28e7.png 这种方案的适用场景是对数据隐私要求极高(纯局域网或禁止数据过第三方云)、常电IPC设备。 其优点是设计架构最简单,该功能不需要依赖于厂商部署专门的云服务,客户数据不经过云服务器的中转,隐私性最好。 缺点也很明显,每次发生的告警事件都要在端侧建立 TLS/HTTPS 握手,这个过程对于低功耗电池 IPC 来说极其耗电。而且如果第三方服务器宕机,摄像头端侧的内部系统很难维持长时间的指数退避重试队列,很容易丢消息。 云端转发 以下是云端转发方案的架构:第三方服务器的URL设置到云端,摄像头通过轻量的长连接协议(如 MQTT、WebSocket)将告警信号发给厂商的云服务器,再由厂商云端服务器组织标准的 HTTP POST Webhook 推送给第三方客户服务器。 !19174867-adc4-4e9f-8e1e-a97065931363.png 这种方案的适用场景是电池类低功耗摄像头、需要高可靠性消息触达的商业化项目。当然相比之下,也是更可靠的方案。 其优点更省电,摄像头端侧只需要发送很小的 MQTT Payload(甚至只发个触发信号),然后就可以快速重新进入休眠状态。而且云端拥有强大的消息队列处理能力(如 Kafka、RabbitMQ),可以轻松实现失败重试、死信队列,这样可以确保告警消息100%送达第三方服务器。另外,这种云云交互的方式安全性也更好,云端可以集中管理各个批次设备的 Webhook URL、密钥和证书等。 WebHooks功能的安全机制 因为是与第三方服务器之间进行通信,那么第三方服务器在通过 Webhook 接收事件告警通知时,一个很大的安全性隐患就是被恶意伪造告警。 因此在这个第三方告警接入的系统设计上,必须至少包含有以下安全机制(主要有第三方告警服务器端来进行设计): - 基于HTTPS 强制加密:也就是说,Webhook 目标 URL 地址必须是 https://,防止通信链路上的中间人攻击,Camera 和 ODM 厂商服务器与第三方告警服务器之间一定要通过 HTTPS 来对通信进行加密且验证服务器身份证的正确性。 - 通过签名机制 (HMAC-SHA256)对告警消息进行加密保护:一般是在发送的 HTTP 消息的 Header 中带上一个 X-Signature字段。该字段的计算方式为:将 Request Body 与客户在后台设置的 Secret Key 进行 HMAC-SHA256 运算,第三方服务器收到后使用相同的密钥进行验签,确认消息确实来源于合法的设备或 ODM 厂商的云端。 Webhook 的 Payload 需要结构清晰,以方便服务器端收到后解析。此外,因为告警事件对应的事件缩略图和录像文件所占的体积较大,Webhook 的 JSON 结构中一般只包含缩略图 URL 或视频下载链接,第三方系统收到 Webhook 后,再通过Payload中包含的链接按需拉取媒体文件。 以下是目前业界标准的 JSON 定义参考: 参考资料 - How-to Setup IP Camera API Webhook Events
5G/LTE工作模式总结
5G和LTE模块的功耗管理是硬件设计和BSP驱动开发中非常核心的一环。为了在随时响应网络和最大限度省电这两个核心因素之间取得平衡,这些模块通常遵循3GPP规范并结合硬件接口,设计了几个梯次的工作模式。本文对这些工作模式进行了总结。 从高功耗到低功耗,5G/LTE模块一般包含以下几种核心工作模式: - 正常工作模式Active - 空闲模式Idle - 休眠模式Sleep - 飞行模式Flight !image.png Active Mode Active 模式是模块的全速运行状态。当设备正在进行语音通话、发送或接收网络数据报文(如通过Socket传输产测数据或视频流)时,模块就处于此模式下。 在这种工作模式下,模块的射频收发器全开,基带处理器也高速运转,模块与基站之间保持持续的RRC Connected状态。这意味着,模块与基站之间已经建立了一条专属的信令通道,并且基站为该模块分配了专用的物理层资源(比如特定的频段、时隙)。也就是说,模块不仅已经连上了网,而且基站已经给它预留了收发数据的专用信道资源,两者随时可以进行数据交互。 在这个 Active 状态下,模块射频链路的具体工作状态如下: - RX (接收端):处于持续激活状态。 - TX (发射端):并非持续常开,而是脉冲式的按需发射。当有业务数据要发送的时候,模块向基站申请资源,基站批准后,TX PA(功率放大器)才会在指定的微秒级时隙内瞬间开启,把报文发射出去,随后立刻关闭 PA 以节省功耗;而当没有业务数据的时候,TX 基本上是静默的,但为了维持RRC Connected的状态,TX 还是会周期性地短暂开启,发送一些底层的控制信令。 对于RF链路而言,其功耗的来源主要是TX部分。在 RRC Connected 的 Active 模式下,即便不需要发送业务数据,只要没掉回 Idle 模式,TX 也会定时与基站通信,这就是为什么 Connected 状态下即使没发数据,底噪功耗依然有上百毫安的原因所在。 此外,在高通、移远、广和通等模组厂商的硬件规格书中可以看到,Active 模式还分为好几种情况:LTE Max. Power Mode,LTE Max. Throughput Mode,SA SISO Max. Power Mode,SA Max. Throughput Mode。这几种子模式的核心区别在于:模块当前工作的功耗瓶颈是在射频前端的 PA(功率放大器)上,还是在核心基带的 DSP(数字信号处理器)上。 !5G_LTE_Power_Modes.png 这些工作模式下的电源功耗数据对于做系统的硬件功耗评估和电源网络(PDN)设计时非常关键:如果设备处于Max Power状态,电源就需要能够扛得住瞬间的大电流波动(比如需要加大的钽电容防掉电);而如果处于Max Throughput状态,由于电流持续在一个较高的均值,此时就要重点解决板卡长时间运行的散热问题。 IDLE Mode 为了尽可能降低 LTE/5G 模块的通信功耗,当数据传输结束的时候,模块就会释放与基站的RRC连接,进入空闲 IDLE 状态。 在IDLE状态下: - 射频发射器 TX 完全关闭,但接收器 RX 会周期性地短暂开启,监听来自基站的寻呼消息(Paging)。这个机制被称为 DRX(Discontinuous Reception,非连续接收)。模块在这个状态下依然附着(Attach)在网络上,因此随时可以快速恢复到Active模式。 - IDLE 状态的功耗表现:中等。通常在十几到几十毫安(mA)之间,具体取决于网络配置的DRX周期长度(周期越长,越省电)。 > 💡 从这个所谓的 DRX 的工作流程上可以看到,这个机制与 WiFi 低功耗模式的 DTIM 机制非常类似。 !image.png 如何由 Active Mode 切换到 IDLE Mode? 模块进入 IDLE 状态的决定权掌握在基站(网络侧)手中,模块本身不能单方面直接断开连接进入休眠状态,否则网络会认为模块异常掉线。 基站侧通常会维护一个 Inactivity Timer(不活动定时器) : - 每次模块与基站之间有数据收发(无论上行还是下行),基站的这个定时器就会清零重置。 - 当数据传输停止,定时器开始计时。如果超过设定的时间(通常在几秒到十几秒不等,由运营商核心网配置)依然没有任何数据交互,基站就会认为这个设备暂时不需要通信了。 - 此时基站会通过控制信道向模块下发一条 RRC Connection Release(RRC 连接释放) 消息。模块收到这条指令后,会主动释放物理层资源,关闭发射机(TX),正式进入 RRC IDLE 状态。 !image.png 此外,为了更加极致的省电,3GPP 在最新的低功耗物联网规范(如 NB-IoT/Cat.M)中引入了 RAI(Release Assistance Indication,释放辅助指示) 功能。模块可以在发送最后一包数据时,带上一个标记,主动告诉基站通信已完成。基站收到后会立即下发 Release 消息,从而大幅节省模块在 Active 状态下的等待时间。 DRX与eDRX LTE模块的 DRX 机制实际上类似于 WiFi 模块的 DTIM 工作逻辑,允许模块周期性地休眠和唤醒来最大程度降低射频链路的功耗,同时又保持与基站之间的连接。在这种工作机制下,模块的 RX 大部分时间(Sleep Duration)都处于关闭状态,但每隔固定一段时间就会定时唤醒监听基站的广播信号,看有没有自己的数据包。通过这种机制就保证了在不漏接寻呼的前提下,大幅压榨了功耗。 在 LTE 模块数据手册的功耗数据部分,我们往往能够看到DRX=64/128/256这样的条件下的功耗数据。这些数字指的是 DRX 周期(DRX Cycle Length)。 在 LTE 和 5G 网络中,1 个无线帧的时长固定为 10 毫秒 (10 ms)。因此,将这些参数换算为实际的物理时间就非常简单了: - DRX = 64: 64 * 10 ms = 640 ms(即每 0.64 秒醒来监听一次) - DRX = 128: 128 * 10 ms = 1.28 s(即每 1.28 秒醒来监听一次) - DRX = 256: 256 * 10 ms = 2.56 s(即每 2.56 秒醒来监听一次) 随着物联网(如 NB-IoT、LTE Cat.M、甚至 Cat.1 bis)的爆发,有些设备(比如智能水表)一天只需要发一次数据,几百毫秒或者几秒钟 RX 唤醒一次还是太费电了。针对这个问题,3GPP 在 Rel-13 标准中引入了 eDRX。eDRX 的核心是超级加倍的休眠时间。它在传统 DRX 的基础上,引入了PTW (Paging Time Window,寻呼时间窗口)的概念。模块可以彻底休眠几十分钟甚至几个小时,醒来后,在 PTW 窗口期内再执行几次传统的 DRX 监听,随后再次进入漫长的深度休眠。 在这个eDRX模式下,模块和核心网在建立连接时,就会协商好 eDRX 的周期长度(比如 41 秒、甚至几十分钟)。在模块进入休眠之前,基站侧和模块会根据 模块 SIM 卡中的 IMSI 的最后几位数字,进行哈希计算决定每一次寻呼时间窗口的时隙。模块进入休眠之后,基站就把发给这个模块的寻呼消息先缓存起来,一直等到那个时隙,才通过天线广播出去,而模块也是在相同的时隙到来的时候打开接收天线,接收来自基站的消息。 !image.png Sleep Mode 首先一点,对于射频前端(RF)而言,IDLE 模式和 Sleep 模式没有任何区别。 在这两个模式下,网络侧的状态都是 RRC Idle,模块的射频接收器(RX)都在执行完全相同的 DRX 周期监听。 这两个模式在本质上的区别在于:LTE/5G模块内部的基带 SoC(数字核心)以及与主控相连的外设总线是否处于挂起状态。 与之相关的,存在以下几个方面的休眠/唤醒等功耗的影响因素: - 外设接口与总线:IDLE 模式下USB 总线处于全速或高速激活状态,单单维持一个高速 USB 连接,通常就需要消耗 10mA 到 20mA 的电流。而Sleep 模式下USB 接口进入 Suspend(挂起)状态,USB PHY 断电或进入极低功耗模式。 - 模块内部主 CPU:IDLE 模式下虽然没有网络数据收发,但模块内部的主 CPU(通常是 ARM 核心)依然保持着较高的时钟频率,处于正常工作(空转)状态;Sleep 模式下,模块的操作系统会切入底层的休眠态,主 CPU 大幅降频甚至进入休眠状态。 - 模块内部DDR:IDLE 模式下,模块内部的 DDR/LPDDR 内存处于正常的读写刷新状态。Sleep 模式下内存控制器进入 Self-Refresh(自刷新)模式,只保留最基础的微弱电流来维持数据不丢失。 通过以上几个方面的功耗优化,LTE 模块在 Sleep Mode 下通常可以降至 2mA 到 5mA 左右。 那么当模块处于Sleep Mode下,当有数据收发需求的时候,模块是如何被唤醒的呢?这个唤醒逻辑,可以分为网络侧和主控侧两个方面。 - 网络侧唤醒:如果有来电或下行数据,模块会被基站寻呼唤醒,随后通过特定的硬件引脚(如 RI 振铃指示引脚)拉低或通过USB Resume中断来唤醒主控。 - 主控侧唤醒:主控如果需要发数据,通常会通过拉低/拉高一个专用的GPIO(如 DTR 引脚)或触发USB唤醒信号,将模块 CPU 从Sleep状态拉起。 Flight Mode 飞行模式 Flight Mode 就比较简单了。一般通过AT指令(如 AT+CFUN=4)或专属硬件引脚(如 W_DISABLE#)触发进入飞行模式。 在模块处于飞行模式下,模块会直接切断射频电路的供电,因此模块与基站断开连接,但基带处理器的其他部分(如SIM卡接口、部分外设)可能还在工作,主控依然可以通过AT指令与模块通信,后续可以通过AT指令再把模块设置为Active状态。 参考资料 - https://www.rfwireless-world.com/tutorials/lte-rrc-state-diagram-idle-connected - 4G | ShareTechnote
毫米波雷达的点云数据是如何构建出来的?
在详细总结毫米波雷达FMCW的工作原理与计算过程 和毫米波雷达是如何测量和计算角度信息的? 这两篇文章中分别详细总结了毫米波雷达测量、推导和计算毫米波雷达距离、速度以及角度方位信息的完整流程,本文从使用毫米波雷达芯片和模块的角度,总结雷达输出的点云数据究竟是如何构建出来的。 毫米波雷达输出的点云数据 简单来说,毫米波雷达所输出的点云数据,是指雷达接收天线收到的回波射频信号经过底层数字信号处理(DSP或硬件加速器)后,从中提取出的一组代表空间中有效反射目标的数据集合。 !image.png 对于一个典型的4D毫米波雷达芯片或者模块而言,其每一帧输出的点云由多个点组成,每个点的数据通常是一个包含多个维度信息的向量:。 - 空间坐标位置 ():检测目标相对于雷达传感器的三维空间位置。这是通过计算信号的飞行时间(距离)和不同接收天线之间的相位差(水平角和俯仰角)解算出来的。在详细总结毫米波雷达FMCW的工作原理与计算过程 和毫米波雷达是如何测量和计算角度信息的? 这两篇文章中已经对雷达如何测试出来这些数据进行了非常详细的总结和说明. - 径向速度 ():这是毫米波雷达的竞争优势所在。依靠多普勒效应,雷达可以在底层相对比较精确地测出该点相对于传感器的瞬时靠近或远离的速度。不需要像视觉算法那样通过前后帧比对来估算速度。 - 信噪比/反射强度 ( 或 ,可选项):表示该点反射回来的信号强度。其中金属物体的反射强度更高,而人体、布料等的反射较弱。 而对于 3D 毫米波雷达而言,因为只具备水平方向上的多发多收(MIMO)天线阵列,缺乏垂直方向的天线布局。因此,3D 雷达只能测出距离 (Range)、速度 (Velocity) 和水平角 (Azimuth)。对应于直角坐标系中,它输出的是数据就只有 。 雷达芯片和模块数据输出的格式 对于雷达芯片和模块的输出数据格式而言,目前尚无跨品牌跨行业的通用数据协议和格式。因此,不同的芯片原厂(如TI、NXP、Infineon)或模块封装厂(如森思泰克、纵目等),其通过串口或CAN总线输出的具体报文结构是私有的。 但无论如何,雷达芯片和模块要输出的数据和信息内容无法也就是以上章节所提到的那些内容。因此,其输出数据的核心信息结构在业界是高度一致的:绝大多数消费类和车规级雷达模块,都会采用 TLV(Type-Length-Value,类型-长度-值) 的数据结构来打包点云帧。 下面以参考资料2给出的 TI mmWave传感器通过 UART 输出检测数据的组织格式为例,对雷达的输出数据状况进行说明。 雷达每处理完一帧(Frame)射频信号,就会向外发送一个数据包(Packet)。这个数据包采用了非常经典的定长帧头 + TLV 变长数据块的设计。 !d84769d5-6ac8-4f1c-8000-5dff98fbb5dc.png 每一帧数据输出都会以一个40字节长度的定长结构 Frame Header 开头,这是解析雷达数据输出的锚点:整个数据帧的大小、以及这个数据帧包含的TLV结构的数量都在Frame Header中定义。 !72144cc0-7681-4e3a-87cb-ae50f9ecaf8b.png 注意其中的 Num TLVs 描述的是这个帧数据包里装了几种不同类型的数据块,可通过 TI 的 guiMonitor 指令要求雷达在一个数据输出帧中同时输出多种数据,如点云数据 (Type 1)、目标追踪列表 (Type 1010)、系统状态信息 (Type 6)等,每一种类型的数据对应一个TLV结构体。 而 Num Detected Obj 代表的是雷达在当前这一帧的物理空间中,真正检测到的有效反射点的数量。这个变量主要是为解析 Type = 1 (Detected Points) 或类似的点云 TLV 数据准备的。在程序中对点云数据所在的TLV结构进行解析时,可以通过这个变量快速获取到所有检测点的点云数据。 对于每一个TLV结构而言,其开头首先是一个定长的8字节,其中包含有这个结构的Type和Length信息: !3815ec78-ee1c-4b05-a4ab-1f77faab2a98.png 对于点云数据的TLV结构而言,Type部分固定是1,Length则代表了这个TLV结构不含TLV Header的Data Length。 TLV结构的Data部分就是连续的点云数据,每个点云数据结构代表了一个有效检测点,定长16字节,对于雷达针对一个检测点的 4 个核心物理量,全部采用标准的单精度浮点数(IEEE 754 标准)。所以这部分的长度就是 4 Bytes * Num Detected Obj !7e1c6452-7075-4d1d-a761-99e1c75795d3.png 雷达点云信息的构建 在真实的物理世界中,雷达发射出的调频连续波(FMCW)会打在汽车、行人、树木、地面,甚至是雨滴上,然后同时反射回来。雷达的接收天线(Rx)最终收到的,是一个把所有这些反射信号全部混杂在一起的复杂的模拟电磁波。 那么,雷达芯片内部究竟是如何从这个复杂的混合信号中,提取出来一个个清晰的 点云数据的呢? 其实,大致的计算过程,在详细总结毫米波雷达FMCW的工作原理与计算过程 和毫米波雷达是如何测量和计算角度信息的? 这两篇文章中已经详细的总结过了。 这里再从完整点云信息构造的角度上,对点云数据的构造过程进行总结: - 1D FFT(距离维度):当混杂着各种回波的模拟信号通过雷达的 ADC 采样变成数字信号后,DSP 做的第一件事就是做一次快速傅里叶变换(Range FFT)。因为 FMCW 雷达的回波频率差直接对应物理距离,所以这一步实际上是在把空间按距离切片,这就初步可以把不同距离的物体分开了。 - 2D FFT(速度维度):为了能够准确测量速度信息,雷达会连续发射一排 Chirp(比如 128 个组成一帧)。然后针对这 128 个结果,在时间维度上再做一次傅里叶变换(即所谓的Doppler FFT)。因为移动物体在连续 Chirp 之间会产生微小的相位差,2D FFT 能把这些相位差转化为速度信息。经过 2D FFT 后,数据变成了一张二维热力图。 !image.png - CFAR(恒虚警率检测):以上第二步得到的充满能量高低起伏的二维热力图中,不仅有目标,还有大量的环境底噪、地面的杂波反射。雷达必须决定哪些是真正的检测目标,哪些是只是噪声?这就是 CFAR(Constant False Alarm Rate)算法的用武之地:当它检查某一个格子(被测单元 CUT)时,会先去评估这个格子周围一圈格子的平均噪声水平。只有当这个格子的能量,显著高于它周围环境的平均噪声加上一个提前设定的阈值时,雷达才认定这是一个真实的检测点。 - 经过这个CFAR算法的处理之后,雷达的检测结过就变成了离散的、有独立坐标的检测点。这就是毫米波雷达点云输出数据的起源。 !image.png - 3D FFT(角度解算):通过以上三步的计算,得到了离散检测点(点云)的距离和速度信息。最后一步,雷达只需要针对那些通过了 CFAR 检测的极少数点,提取不同接收天线(Rx)之间的信号相位差,进行第三次傅里叶变换,计算出该点在水平和俯仰方向的角度。 最终,每个孤立的检测点和能量峰,都拥有了完整的距离、速度、角度(方位角和俯仰角)以及反射强度等信息,这些信息会被打包成标准的 TLV Type 1 数据,通过串口按照上面描述的协议格式发送出来。 !image.png 参考资料 - Lidar 轻科普 | 激光雷达、摄像头、毫米波雷达,谁才是真正的智能汽车之眼? - Understanding UART Data Output Format
毫米波雷达是如何测量和计算角度信息的?
在详细总结毫米波雷达FMCW的工作原理与计算过程 一文中详细总结了毫米波雷达检测目标距离和速度的理论推导和计算公式,本文则详细整理了毫米波雷达所输出点云信息中的角度概念以及角度数据的计算流程。 角度的定义 在毫米波雷达输出的点云(Point Cloud)数据中,其中所包含的角度信息本质上指的是目标反射回来的电磁波的到达角(Angle of Arrival, 简称 AoA)。 在三维空间的产品应用中,这个角度信息通常包含两个维度: 1. 方位角(Azimuth / 水平角): 目标在雷达水平面上的偏转角度,左右方向。例如,雷达探测到前方车辆在正前方偏左 15° 的位置。 2. 俯仰角(Elevation / 垂直角): 目标在雷达垂直面上的偏转角度,上下方向。例如,雷达探测到前方的天桥或路标在正前方偏上 10° 的位置。 有了距离 R + 方位角 φ + 俯仰角 θ 这三个球坐标量,再结合雷达自身的位置,就可以换算成笛卡尔坐标系下的 (x, y, z),这也是雷达输出的点云数据在空间中能够呈现出目标轮廓的原因。 !image.png 雷达测角原理 雷达的单根天线通过调频连续波(FMCW)的频率差来测距,并通过多普勒频移(相位差)来测速,单根天线是无法测角角度的。 要获取角度信息,雷达必须依赖多天线阵列(MIMO技术,即多个发射天线 TX 和多个接收天线 RX)。其核心测角原理是相位差测角法。 当雷达发射天线发射出去的雷达波打到目标上并反射回来时,目标所反射的回波,是一排大致平行的电磁波(平面波)打向雷达的多根接收天线。 假设目标物体在雷达正前方偏离角度为 的位置。由于雷达板上的接收天线之间存在固定的物理间距 (通常设计为半个波长 ),回波到达相邻两根天线的时间会有一个微小的先后差异:它到达第一根接收天线(RX1)后,还需要再多走一段才能到达第二根接收天线(RX2)。 假设两根接收天线之间的物理距离是 。根据直角三角形的三角函数,这段多走的路程(波程差) 。 !image.png 而因为电磁波是正弦波,多走了这一段距离 ,表现在接收到的信号的波形上,就是一个相位的偏移(即对于两个天线而言,接收到的波形总有一个固定的相位差)。波长 对应一个完整的周期( 相位)。那么多走 距离,对应的相位差 就是: 接下来再从以上等式反求角度 。因为雷达的硬件芯片能够精准地测量出 RX1 和 RX2 收到信号的相位差 (只需要对RX1和RX2接收的波形分别进行类似测距计算的采样的FFT,从FFT的计算结果就可以得到相位,然后计算两个信号的相位差即可),而且两根接收天线之间的间距 是提前设计好的,而雷达发射电磁波的波长 也是固定的,所以目标角度 就可以很轻松的根据上面的公式推算出来: 以上就是雷达测角的终极本质:通过对比不同天线接收到信号的相位差,利用几何三角函数反推出目标的角度而已。 3D雷达与4D雷达 以上所总结的雷达测角的原理非常简单,但是需要注意:如果雷达的两根接收天线是在水平方向上一字排开,它就只能测方位角,也就是水平方向上的角度,这就是所谓的3D雷达。 原因很简单:如果所有的接收天线都排在同一条水平线上时,这些天线之间只有水平方向上的间距。在这种情况下: - 当目标在左右(方位)移动时,电磁波到达各根天线的路径长短不同,产生相位差,雷达可以据此根据以上的流程算出方位角。 - 但是当目标在上下(俯仰)移动时,由于电磁波的回波从上方或下方平行打过来,它到达每一根水平排列的天线所走的距离是完全一样的。因此,天线之间产生的垂直方向相位差为 0。雷达无法分辨目标究竟是在天上还是在地下,这也就是传统3D雷达在车载电子领域中把天桥和路面障碍物混为一谈的原因在。 而 4D 雷达是在 3D 雷达的基础上引入了垂直方向的探测能力。在具体的系统设计实践中,通常会采用巧妙的二维平面阵列(2D Planar Array)或者 MIMO(多输入多输出)虚拟天线技术。也就是在雷达天线的排列设计中,把发射天线(TX)和接收天线(RX)交错排列,发射天线之间也故意设计出一定的高度差。这样当多发多收同时工作时,在算法层面上会组合出成倍的虚拟天线点,这些虚拟点在水平和垂直方向上就构成了一张二维面阵。 !image.png 其中横向延伸的虚拟天线阵列利用天线的水平距离差测水平方向上的方位角,纵向(有高度差)延伸的虚拟天线阵列则利用天线的垂直距离差去测上下方向上的俯仰角。 总结一下,毫米波雷达领域的行业内对雷达维数(D)的定义如下: - 3D 雷达测量 3 个维度: 距离(Range)、速度(Doppler/Velocity)、方位角(Azimuth)。 - 4D 雷达测量 4 个维度: 距离、速度、方位角 + 俯仰角(Elevation)。 _而我们经常看到的雷达点云数据中的 3D 空间坐标(X, Y, Z)正是由距离、方位角、俯仰角这三个物理量通过三角函数解算出来的。_ 雷达的角度分辨率 与雷达对于距离和速度的测试相同,雷达对于角度的测量也存在一个最小分辨率的概念,就是雷达的角度分辨率。 在雷达工程中,角度分辨率(Angular Resolution)是指雷达在相同距离、相同速度下,能够区分两个相邻物体的最小角度差。如果两个目标(比如行人和旁边的停放车辆)的角度差小于雷达的角度分辨率,雷达的 DSP 就会把它们算作同一个回波峰值,在其点云数据上输出一个大的融合点,而不是两个分开的独立目标。 现代 4D 成像雷达大多采用单芯片大阵列(如 4发4收、4发6收)甚至多芯片级联(Cascaded,如 4颗芯片拼成 12发16收)的天线设计模式,其水平方位角分辨率,可以做到 1° ~ 1.5° 的高精度,垂直俯仰角分辨率大约在 2° ~ 5° 之间。 角度分辨率如何计算? 在雷达和天线理论中,角度分辨率的本质是天线阵列的主瓣宽度。物理学上的瑞利判据指出,当一个目标的波峰刚好落在另一个目标的波谷(第一个零点)时,这两个目标刚好能被区分。 !image.png 而对于一个长度为 的均匀线阵,其天线方向图(波束形状)可以用 函数来描述,其 3dB 波束宽度(即功率下降一半的角宽度,工程上定义为角度分辨率 )的理论计算公式为: !image.png 为了速算方便,通常抹去 的系数,取近似值: 因为 弧度 ,所以 1 弧度 。将其代入上面的公式,我们得到角度制的公式: 假设有 根接收天线,天线之间的间距为 ,那么阵列的等效孔径长度为: 把这个 代回以上角度计算公式中: 以上就是在工程上快速计算雷达角分辨率的速算公式。可以看到,想要提高角分辨率,唯一的出路就是增加接收天线的数量 。 按照以上的速算公式,要想达到 1° 的分辨率,就需要114根间距为 的接收天线?这当然是不可能的。这就引出了雷达的MIMO(Multiple-Input Multiple-Output,多输入多输出)与虚拟天线阵列(Virtual Antenna Array)技术。 MIMO 虚拟天线阵列 在雷达的天线设计中,硬件上无法做到大量的真实接收天线,但工程实践中可以用少量发射天线(TX)和接收天线(RX)相乘,在雷达的工作流程中虚拟出大量的天线,从而通过这些虚拟天线来提升角分辨率的性能。 大致的工作流程如下: - 发射天线 TX1 发射一个 Chirp 信号,板子上的 4 根真实接收天线(RX1 ~ RX4)收到回波。此时系统获得了 4 个空间相位采样点。 - 极短的时间后,TX1 停止,TX2 发射信号。而在 PCB 布局时,故意把 TX2 的物理位置往侧边挪动了一段精确的距离(通常是 4 倍的半波长)。这样当 TX2 发射信号打到目标再反射回来被 RX1~RX4 接收到时,由于 TX2 的位置偏移,电磁波多走了一段路。 - 雷达的 DSP 进行计算时,TX2 发送时 RX1~RX4 收到的信号相位,数学上等效于 TX1 发送时,在其右侧凭空多出来的 4 根新接收天线(RX5 ~ RX8)收到的相位。 !image.png 因此,通过 3 根 TX 分时发送,配合 4根 RX 接收,雷达的软件层成功解算出了 3 4 = 12 根虚拟天线的相位数据。 如果使用 TI 或 NXP 的旗舰单芯片(如 4TX / 4RX),可以通过以上的 MIMO 方式产生出多达 16 根虚拟天线( 分辨率)。 而如果将 4 颗这样的芯片再进行级联的话,如做到 12TX 和 16RX,就可以虚拟出 根虚拟天线。 以上提到的当代旗舰级别的 4D 雷达能够实现高精度水平和俯仰角分辨率,就是通过这种虚拟天线的方式来达成的。 参考资料 - 如何利用毫米波雷达点云进行多目标跟踪?-电子工程专辑 - (28 封私信 / 4 条消息) 一文读懂毫米波雷达(含4D毫米波雷达) - 知乎 - 从原理到应用教你了解毫米波雷达_企业动态_资讯_无人机网(www.youuav.com)_无人机专家--无人机专业网络平台(www.youuav.com)! - 雷达原理_Part1 - 博客侦探 - 博客园 - MIMO雷达技术杂谈 - 吴建明wujianming - 博客园
详细总结毫米波雷达FMCW的工作原理与计算过程
在 一文搞懂mmWave Sensing雷达技术的工作原理一文中,对雷达以及毫米波雷达mmWave的基本工作原理和两种工作模式的计算过程进行了简要的总结。本文主要针对mmWave Sensing的FMCW模式的工作原理以及距离和速度的计算流程进行详细的整理,从而对该工作模式雷达的概念和工作过程建立更深刻的理解。 FMCW模式发射信号的组织与结构 如一文搞懂mmWave Sensing雷达技术的工作原理一文所总结,在毫米波雷达的FMCW(Frequency Modulated Continuous Wave)模式下,雷达不发射传统的离散脉冲,而是发射一种频率随时间线性增加的连续正弦波,这就是 Chirp 信号。 !image.png 一个 Chirp 的核心物理特征可以通过以下几个参数来定义: - 起始频率 ():例如 77 GHz。 - 带宽 ():频率扫过范围,例如 4 GHz。带宽决定了雷达的距离分辨率(Range Resolution),带宽越高,距离分辨率越精细,更容易分辨距离靠近的两个物体。 - 持续时间 ():频率从 扫描到 所花费的时间,例如 40 µs。 - 频率斜率 ():频率变化的速率,公式为。 如果只是要测量静态物体的距离的话,用一个Chirp就足够了,但是如果还要测试物体的运动速度,就需要连续的多个Chirp。因此,雷达的数据是按帧(Frame)进行组织的,每个Frame包含有连续的多个Chirp信号,以便于后续的 NPU 或 DSP 进行周期性的数据吞吐和目标检测。 对于一个 Chirp 信号而言,其完整的微观时间轴主要包含以下两个阶段: - Inter Chirp Idle Time:发射机不发射有效信号,频率合成器迅速回落到起始频率 并锁定。 - Tx Start:发射机开启,频率开始线性上升,频率从 上升到 。 一个Frame则包含有一组连续的相同Chirp信号,Frame 的关键参数如下: - Number of Chirps(每帧所包含的 Chirp 数量):例如一帧包含 128 个 Chirp。这个数值决定了雷达的速度分辨率。 - Frame Periodicity(帧周期):例如 33 ms(相当于约 30 FPS)。 - Active Frame Time(有效帧时间):128 个 Chirp 连续发射所占用的时间。 - Inter-Frame Time(帧间间隙):一帧发射完毕后到下一帧开始前的时间。雷达的射频前端在这段时间通常进入低功耗状态,后端芯片(如 DSP、ARM 或 NPU)利用这个时间段全速处理当前帧所生成的 ADC 原始数据。 下图是一个包含有连续Chirp信号的Frame的时间轴结构: !image.png 下面使用一个例子,来对雷达发射的Chirp和Frame信号的时间轴进行说明: - Chirp 持续时间 ():50 µs - Chirp 空闲时间 (Idle Time):10 µs _(因此,发射一个完整 Chirp 的周期是 60 µs)_ - 每帧 Chirp 数量:128 - 有效发射时间: ms - 帧周期:33 ms 因此,按照以上的参数,整个雷达系统的发射机运行流程为:发射机在每 33 ms 的周期内,只有前 7.68 ms 是在以极快的时间间隔(60 µs)连续不断地发射 128 个 Chirp 信号。剩下的约 25 ms 时间内,发射机关断,等待下一帧触发。 雷达的系统结构与中频信号 FMCW毫米波雷达系统的结构如下图所示: !image.png 该框图中混频器Mixer的作用,是对当前时刻的发射信号与接收机接收到的回波信号混频相乘,对混频后的信号做低通处理,得到一个用于进行后续计算的中频信号。 假设当前时刻的发射信号为,当前时刻的接收回波信号为。 那么通过混频器处理并经过低通滤波后得到的中频信号是: 后续对于距离、速度和角度的计算,都是在这个中频信号的基础上进行计算。 距离的计算流程 理解距离计算的关键在于:接收器受到的RX 信号在时间上是 TX 信号的延迟版本 。 !0dd49612-962a-4e37-8697-ff2711848792.png 假设雷达信号从发射机发出到接收到收到回波的电磁波信号飞行时间为 ,那么信号往返目标的时间延迟公式就是 ,其中 是物体距离, 是光速。 因为 TX 信号的频率是随时间线性增加的,所以延迟了 时间的 RX 信号在任意时刻与 TX 信号相减,都会得到一个恒定的频率差,这个频率差就是中频信号的频率。 根据几何相似性,中频信号的频率 等于斜率 乘以时间延迟 ,再结合上面的时间延迟公式,就可以得到距离的最终计算公式: 因此只要得到中频信号的频率 ,系统就能直接反推出目标的距离 。 DSP的计算流程 对于雷达系统的DSP而言,计算流程如下: - ADC 采样:雷达的模拟混频器输出的是一个模拟中频(IF)正弦波,DSP 首先要通过 ADC(模数转换器)对其进行采样。设定 ADC 的采样率 (例如 6.4 Msps)和每个 Chirp 采样的点数 (例如 256 点),经过这个采样步骤后得到一个长度为 的数组。 - 信号加窗:在直接做 FFT 之前,为了应对 FFT 对固定长度数组计算中存在的频谱泄露问题,通常会把 个采样点与一个相同长度的窗函数(如 Hanning 窗或 Blackman 窗)相乘。 - 执行FFT计算: DSP 的硬件加速器(HWA)或 DSP 核对 个加窗后的时域数据点执行离散傅里叶变换,计算结果是一个包含 个复数(实部+虚部)的频域数组。根据奈奎斯特定理,通常只需要看前 个点。这 个点在雷达术语中被称为 Range Bins(距离单元) 或 Index 。 - 幅度计算与寻峰:FFT 的输出是复数域的,代表相位和幅度。 DSP 遍历这 个 Range Bin,计算每个点的幅度 。在只有一个检测目标的简化情况下,DSP 只需要简单地找出这 个点中数值最大(能量最高)的那个点,并记录下它的索引号,记为 Index 。 - 如果是有多个检测目标,那么在遍历 FFT 的输出幅度时就会找到多个峰值,记录下这些峰值点的index即可。 - 物理量换算:这一步的作用就是要把上一步得到的 index 转换成实际的距离单位 m,按照以下流程进行转换即可。 !cd67c01b-6957-40fe-8ce8-615c3c75addd.png 每一个 Bin 代表的频率跨度(频率分辨率 )由 ADC 决定:,这里的 为 ADC 的采样率。 因此,峰值(所在Range Bins的index为 )所在的中频频率就是:。 再结合上面的雷达距离计算公式: ,稍作变换得出距离 :。 最终得到的距离计算公式为: 公式括号里的部分 ,在雷达初始化时就是一个常数,这个常数实际上就是雷达的单 Bin 距离分辨率()。 速度的计算流程 既然基于单个 Chirp 的测量,就可以得到物体的距离,那么如果对多个 Chirp 的距离进行对比,是不是就可以很容易的计算出来物体的运动速度?答案是否定的。 假设目标在以速度 移动,雷达连续发射了两个间隔为 (Chirp 周期)的相同 Chirp 信号。在发射第一个 Chirp 和第二个 Chirp 的极短间隔内(例如 60 µs),目标只移动了极其微小的距离:,这个距离对于普通运动物体而言只是微米级别,这么微小的距离差在 FFT 的频谱图上根本看不出位置(频率)的变化,两个 Chirp 在 FFT 后的峰值依然出现在同一个距离 Bin 里。 但是,由于毫米波的波长 极短(77GHz 的波长大约只有 3.9 mm),这个微小的距离差会导致两个 Chirp 的中频信号在复数域产生明显的相位差 。 电磁波在空间中每往前走一段物理距离 ,它所走过的距离相位的变化为: 假设雷达与目标之间的距离是 。但是,雷达发射的 Chirp 信号需要先飞到目标,再从目标反射飞回接收天线。因此,电磁波在空气中实际飞行的总路程是 。 我们将总路程 代入第一步的公式中,而目标移动的微小距离 ,就得到了雷达接收信号相位差的物理公式推导为: 通过以上这个公式,可以反推出目标的速度 : 基于以上公式,只要得到了两个Chirp信号的相位差,就可以计算出目标的运动速度。 !ca6da295-8d3b-4131-9c26-244d9ac8c5d0.png > 💡 这里有个最大不模糊速度 ()的概念。由于相位是通过三角函数计算的,三角函数具有周期性。为了保证速度测量的唯一性(不产生模糊),两次采样间的相位差绝对值必须小于 。由此可以推导出雷达能测量的最大相对速度:。这说明:Chirp 周期 越短(发射越密集),能测量的最大速度就越高 。 DSP的计算流程 雷达系统的DSP计算速度的流程如下: - 构建雷达数据阵列:在一帧内,ADC 采集了 个 Chirp(例如 128 个),每个 Chirp 采样 个点(例如 256 点)。DSP 首先对每一个 Chirp 的 256 个时域采样点进行 FFT 计算(距离 FFT)。 每个 Chirp 采样信号的 FFT 复数输出结果(包含幅度和相位)会被写入内存,拼成一个 的二维矩阵阵列。 - 距离门锁定与数据抽取:在短短一帧数据时间(实际上只有几毫秒)内,普通运动目标的物理位移非常小,一般不会跨越雷达的距离分辨率单元。假设在每个 Chirp 信号的FFT结果序列中,都是在第 个距离 Bin 找到了目标的能量峰值。这一步,就是要将所有 个 Chirp 在第 个 Bin 上的复数数据(包含有幅度和相位信息)抽取出来,从而组成一个全新的、长度为 的一维复数数组。 - 加窗:与距离计算的逻辑相同,为避免后续进行2D FFT计算时频谱泄露,DSP 将这个长度为 的一维复数数组中的每一个元素,与一个一维窗函数(如 Hanning 窗)的系数相乘。 - 执行 2D FFT(Doppler FFT):DSP 的傅里叶变换单元对这个加窗后的长度为 的复数数组执行一次 点的 FFT 计算(这个FFT计算也就是所谓的2D FFT计算),其计算结果是一个长度同样为 的复数数组。这个数组的每一项代表一个特定的多普勒频率单元(Doppler Bin)。 - 寻峰与速度物理量换算:DSP 计算 2D FFT 输出数组中每个元素的模值(幅度 ),得到速度能量谱,从中找出能量最大的那个多普勒 Bin 的索引号,记为 Index 。 以上通过2D FFT计算出来的这个速度能量谱,总共有 个 ,实际上也就意味着把整个圆周期对应的 分为 份,以上的相位差公式计算每一份相位差的等式为: 因此最后得到的速度分辨率(实际上也就是速度能量谱中每个bin对应的速度单位值)就是: 既然上面计算得到的速度能量谱中峰值位于第 个bin,那么其对应的速度就是: 如果有多个目标怎么办? 以上对于检测目标的距离和速度计算流程的总结,主要考虑的是针对检测场景中只有一个目标的简化情况。那么如果检测场景中同时存在多个目标怎么办呢? 在这种情况,测试待检目标的距离相对比较容易。 如果检测场景中有多个目标的话,经过信号反射回波、ADC采样以及在DSP中进行 FFT 计算后,最终会在 FFT 的距离谱(Range Bins)上会出现多个不同 index 的尖峰,每个尖峰对应于一个检测目标的距离。 当然在这种情况下,如果两个物体之间的距离过近,小于这个雷达的距离分辨率的话,在距离谱上就出现在相同的Bin Index,雷达就没办法识别开了,只能显示为一个目标。 !7a57f0d5-8c03-444f-b34d-b653813d82aa.png 那么两个相同距离的目标速度不同的话,会发生什么情况呢?此时,由于这一个距离 Bin 里面混合了两个目标的相位,提取出来的相位序列将是一个混乱的叠加态,这会导致雷达无法正确识别和分辨两个目标的速度。 所以在这种情况要测量速度的话,就不能先在距离谱中找到目标,然后只针对这个目标在所有Chirp上的数据去计算2D FFT。而应该是: - 先对整个 Frame 中所有 个 Chirp 执行一次 1D FFT,把计算结果拼接在一起,得到二维的 Radar Data Matrix(行是距离 Bin,列是 Chirp)。 - 这个二维矩阵中的每一列,对应的都是一个距离 Bin 中检测目标的幅度和相位在一个 Frame 中连续 N 个Chirp的变化情况。其中,因为一个Frame的时间很短,所以这个序列中的幅度变化会非常小,但是相位则会根据检测目标的速度情况有显著的变化。 - 如果一个距离bin中有多个目标的话,这个序列中反映的幅度和相位就是两个目标的叠加影响结果。 - 直接对 Data Matrix 的每一行(每一个距离 Bin)都执行一次 2D FFT(Doppler FFT)。 - 如果一个距离bin中有一个目标的话,这个2D FFT的结果就是能够根据序列中数据相位变化的情况找到与之对应的距离。 - 而如果一个距离bin中有多个目标的话,这个2D FFT不仅能够找到距离,还能够区分把不同速度所引起的相位差异找出来。 - 经过全矩阵的 2D FFT,DSP 会在内存中生成一张二维的热力图。横轴是距离,纵轴是速度,颜色深浅代表能量(幅值)。 - 接下来就是直接在这张二维热力图上寻找二维尖峰的,每个尖峰对应于一个检测目标的速度数据。 可以看到,在这个热力图上,两个处于相同距离Bin、不同速度的物体可以清楚的识别出来。 !6334ac9c-e43c-4b20-83d8-a8aaef4c58bb.png 参考资料 - The fundamentals of millimeter wave radar sensors, Texas Instruments.
一文搞懂mmWave Sensing雷达技术的工作原理
总的来说,雷达(最初是“无线电探测和测距”的缩写)是一种通过向被测目标发射电磁波(无线电波),然后测量被反射回来的无线电波来探测到目标的距离、速度和方向的设备。 在雷达技术的发展史上,脉冲法(Pulse Method)和调频连续波(FMCW)是两种最经典且截然不同的体制。脉冲法是传统雷达(如大型军用雷达、早期气象雷达)的基石,而 FMCW 则是现代消费类和车载毫米波雷达的绝对主力。 本文详细总结了脉冲法和在毫米波雷达领域应用非常广泛的FMCW模式的工作原理。 什么是毫米波? 毫米波(mmWave)顾名思义,是指波长在1毫米到10毫米之间的电磁波,其对应的频率范围大致在 30 GHz 到 300 GHz 之间。它们被称为毫米波,正是因为它们的波长以毫米 (mm) 为单位进行测量的。 > 当然事实上,毫米波的频率范围并没有严格的定义。例如,目前分配给全球5G通信的26 GHz和28 GHz频段也被视为毫米波。 目前在在消费类和车载电子中,目前最常被工程化应用的是 24 GHz(正逐渐被淘汰)、60 GHz、77 GHz 和 79-81 GHz 频段。 下图显示了毫波波在无线电波分类的频段和波长范围。它们被称为毫米波,正是因为它们的波长以毫米 (mm) 为单位进行测量的。 !4ac5c170-7f85-4611-916c-6edef73c9c73.png 脉冲法的工作原理 脉冲法的工作原理和过程非常符合我们的直觉,它的核心思想:雷达发射一个极短的高功率电磁波脉冲,然后静静地等待接收反射回来的信号。 需要注意,在脉冲法的工作模式下,雷达每次发射出去的那个极短的脉冲(比如持续 1 微秒),其内部包含的是高频的震荡电磁波。这个波的频率就是载波频率,它在脉冲持续期间通常是固定不变的。相当于雷达的每次发射,都是在这个极短的时间内(如下图的蓝色脉冲)发射一个固定载波频率的电磁波信号,其接收到的回波自然也就是相同的载波频率信号。 !4f728773-1635-4da8-b096-849e907b5378.png 因此,使用脉冲法测距的工作原理就是利用发射信号和接收信号之间的时间差(ToF)。电磁波以光速 传播,雷达记录发射脉冲的时刻和接收到反射脉冲的时刻,计算出时间差 (即飞行时间 Time of Flight),然后使用以下公式就可以计算出来物体的距离: 而对于使用脉冲法进行测速而言,则需要使用到多普勒相位移(Doppler Phase Shift)。其工作原理是:如果目标是移动的,单个脉冲就只能测出距离,无法直接测速。在这种情况下要测速的话,雷达必须发射一串脉冲(Pulse Train)。当目标移动时,相邻两个脉冲往返的距离发生了微小变化,这会导致反射回来的电磁波相位发生改变。雷达通过对比连续多个脉冲的接收相位差,利用多普勒效应解算出目标的径向速度。 雷达如何一次性测试多个目标的距离? 当雷达的脉冲发射出去后,雷达的接收机就会一直处于开启状态,对应的高速 ADC会连续记录接收到的信号电压。此时,雷达发射波覆盖范围内的所有目标,处于不同距离的这些目标会向接收机反射各自的回波,因此接收机的电压曲线上会出现多个波峰。 当然,这里有一个雷达的距离分辨率(Range Resolution)的概念。这个概念是指雷达能够区分两个靠得很近的物体的能力。比如,对于汽车电子领域的雷达侦测而言,一辆车旁边紧贴着站着一个人,雷达在屏幕上是显示一个大圆点,还是两个独立的小圆点?如果两者之间的距离过近,雷达接收机接收到的回声就没法区分,只能认为是一个目标。 只要这些物体在距离上的间隔,大于雷达的距离分辨率,它们在雷达的接收机上接收到的就是先后到达的、互不重叠的独立回声。雷达的 DSP 只需要去利用这条时间轴上有几个波峰,以及它们各自的时间戳,就能一次性解算出所有目标的距离。 !cd2e2df7-ef26-4379-8eb4-17727a7ac8b3.png 为什么消费级/车载电子的雷达无法使用脉冲法? 这主要是因为: 毫米波雷达要求的距离分辨率通常在厘米级。 在脉冲雷达中,为了区分这两个目标,它们各自反射回来的回声(脉冲)在时间轴上绝对不能重叠,也就是说这两个目标之间的距离一定要大于雷达系统的距离分辨率。 假设两个物体前后相距 ,电磁波打到后面那个物体再返回,需要多走 的距离,这段多出来的飞行时间就是: 而为了让前一个物体的回声彻底结束,后一个物体的回声才开始,雷达发射出来的脉冲本身的持续时间(脉冲宽度 )就必须小于这个时间差 。 按照以上公式和理论,如果要区分的两个目标的最小距离是15cm,那么雷达发射器每次发出的脉冲宽度就必须满足以下条件: 但是,要在低成本车规级和消费级的雷达芯片上处理 1ns 的信号会存在很大问题: - 雷达探测距离的远近,取决于发射出去的总能量(能量 = 功率 时间)。如果只有 1ns 的时间来发射能量,为了让电磁波飞到 100 米外还能有足够的回波,就必须在这极其短暂的 1 ns 内,爆发出几百甚至上千瓦的瞬时峰值功率(Peak Power)。这在传统的基于CMOS工艺的芯片上是做不到的。 - 在接收端同样会存在问题:根据奈奎斯特采样定律,想要在数字世界里还原一个 1 纳秒宽的波形,雷达接收机 ADC 的采样率至少要达到几个 GSPS。这对于几美金的消费级和汽车电子领域的芯片同样是不现实的。 - 另外,要精确计算几十皮秒( 秒)级别的时间差来测距,对于雷达系统内部时钟的要求也极高,芯片内部的时钟(PLL/VCO)必须极其稳定,抖动极小。这种高精度的时钟网络在低成本 SoC 上很难实现。 这就是为什么在消费类和汽车电子领域,毫米波雷达最终抛弃了简单的脉冲法,转向了 FMCW(调频连续波)的原因所在。 FMCW模式的工作原理 消费级和车载领域目前最主流的毫米波雷达技术是 FMCW(Frequency Modulated Continuous Wave,调频连续波)。 下图是一个典型的FMCW毫米波雷达的系统框图: !c75428c7-bf61-48d9-bb3a-25919bfa5f1d.png 在FMCW模式下,整个雷达系统的工作步骤如下: - 步骤 1:发射波生成。系统中的合成器(Synthesizer)产生特定频率的毫米波信号,这个信号通过分配器(Splitter)分成两路:一路送往发射天线(Tx antenna),用于向外发射。另一路送往混频器(Mixer),作为后续处理过程的参考信号。 - 步骤 2:毫米波发射。经过放大器(Amp)放大后的毫米波信号由发射天线向目标(如汽车)发射。 - 步骤 3:接收反射波。目标物体会反射部分毫米波信号,反射波由接收天线(Rx antenna)接收,并通过放大器放大后送入混频器Mixer。 - 步骤 4:混频与信号处理。在混频器Mixer中,将接收到的反射波与参考信号进行混频相乘,过滤掉高频部分后,会得到一个低频的 中频信号(IF Signal, Intermediate Frequency)。将该中频信号送入数字信号处理器(DSP),通过计算可以得到目标的距离、速度等信息。 需要注意的是,在该模式下,毫米波雷达并不像脉冲雷达那样发射短暂的电磁波脉冲,而是持续、不间断地发射频率随时间线性变化的连续波,这种波形被称为 Chirp(线性调频脉冲)。 !fig-mmwave-003-en.png 中频信号的计算流程和工作原理 在极短的一个瞬间,可以把发射信号(Tx)和接收信号(Rx)看作是两个高频的余弦波(正弦波同理)。假设在某一时刻: • 发射信号 (Tx): 频率为 (比如 77.005 GHz),表达式为 • 接收信号 (Rx): 频率为 (比如 77.000 GHz),表达式为 对于雷达硬件中的混频器而言,其物理作用就是将这两个电压信号进行乘法运算。 根据三角函数的积化和差公式: 将上面的 Tx 和 Rx 的表达式代入,混频器输出的原始信号 就变成了: 以上这个公式的结果,两个单一的高频波相乘后,变出了两个全新的波: - 和频分量 (): 这两个频率相加,变成了一个大约 154 GHz 的超高频信号。 - 差频分量 (): 这两个频率相减,变成了一个只有 5 MHz()的低频信号。 而在混频器的输出端,硬件电路上一定会紧跟着一个低通滤波器。这个低通滤波器的效果,就是把上面和频后的超高频信号过滤掉,只保留差频信号分量。这个差频分量信号,也就是后续用于进行距离和速度计算的中频信号。 而这个中频信号经过以上处理以后只有5MHz,低成本的处理器也可以轻松应对。 !e6ffd6c7-fec8-43d7-86bc-0a56bd967181.png 通过中频信号计算距离和速度 基于以上得到的中频信号来计算距离的过程比较简单。因为中频信号的频率实际上是收发信号的频率之差,所以这个频率 实际上完美正比于目标的距离 。 其中 是 Chirp 扫频斜率(), 是光速。 那么雷达的接收机在接收到回波信号,并对其生成的中频信号进行采样以后,只要对每一个 Chirp 的采样点执行一次一维快速傅里叶变换,将时域的中频信号转换到频域,得到中频信号的频率 以后,就可以使用以上公式计算出来距离了。所以单个 Chirp 信号就可以计算得到目标的距离。 计算速度就稍微麻烦一些,需要依赖于连续两个 Chirp 信号序列的计算结果。 如果目标在移动的话,因为连续两个Chirp之间的时间间距非常短,因此一般情况下它在连续的 Chirp 之间会产生极其微小的位移(通常在微米级),这个微小位移无法显著改变计算得到的距离,但却会导致相邻两个 Chirp 的 FFT 峰值处的复数相位 发生一定的线性漂移。 相邻两个Chirp之间的相位差可以使用以下公式表示: 其中 是目标相对速度, 是 Chirp 周期, 是电磁波的波长。 所以通过FFT计算到连续两个 Chirp 序列FFT峰值的相位差,就可以使用以上公式倒推计算出来目标的相对运动速度 。 参考资料 - What Is mmWave Radar? Principles and Usage Examples | Murata Manufacturing Articles
DDR和LPDDR为什么无法相互兼容?
DDR和LPDDR在做系统设计的过程中,是否可以相互兼容?对于一个主控SOC而言,如何从DDR和LPDDR中做出正确的选型和设计?本文尝试详细解释和总结以上DDR和LPDDR的兼容性问题。 DDR和LPDDR无法直接兼容 我们在进行电子产品系统设计中所面对的DDR和LPDDR这两种内存标准,面对的实际应用场景是截然不同的。 - 标准DDR主要针对PC、服务器等对功耗不敏感但要求极致容量和通用性的应用场景。 - 而LPDDR(Low Power DDR)则专为智能手机、笔记本电脑、穿戴设备和各类边缘计算设备等对功耗/空间极度敏感的场景设计。 虽然它们都属于SDRAM(同步动态随机存取内存)的范畴,且名称相似,但在具体的硬件设计和元器件选型中,DDR和LPDDR是绝对不能直接相互兼容或替换的。 !image.png 为什么DDR和LPDDR无法兼容? DDR和LPDDR之间无法相互兼容的原因,体现在多个方面。既包括DDR控制器和物理层PHY实现的电气规范方面,也体现在其内部的模块架构方面,这一点在PSRAM能成为DDR缺货的解决方案吗?和PSRAM和LPDDR是如何降低功耗的?这两篇文章中已有简单的介绍。 以下对两者之间无法兼容的细节问题逐一进行总结和梳理。 电气电平不同 如PSRAM和LPDDR是如何降低功耗的?一文所总结的,LPDDR为了进一步降低功耗,把其IO的标准工作电压降到了1V以下。 - 纯标准DDR控制器: 其内部的 PHY(物理层)是为标准 DDR 设计的。以 DDR4 为例,控制器默认输出的 I/O 电压(VDDQ)是 1.2V(POD 电平标准)。该标准允许较大的信号摆幅,驱动能力强,目的是为了应对较长的PCB走线以及DIMM插槽带来的寄生电容和信号衰减,因此对于PCB上的走线要求没有那么高。 - LPDDR芯片: 以 LPDDR4X 为例,它的核心电压可能是 1.1V,但它接收数据和指令的 I/O 引脚(VDDQ)极其脆弱,标准工作电压是 0.6V(LVSTL 电平)。该标准的信号电压摆幅极小(通常只有几百毫伏)。这种微弱的信号根本驱动长距离的走线,因此LPDDR在物理层上的设计是面向近距离传输的,且对PCB布线的阻抗控制要求极为苛刻。 总线引脚定义不同 标准 DDR 采用的是分离总线设计。在主控SoC和DDR之间连接的地址线(A0-A17)、命令线(RAS, CAS, WE)、数据线(DQ)都是分开的,引脚极其繁多。 而为了把智能设备的PCB面积压榨到极致,LPDDR 标准则把上述所有独立的控制线和地址线,全部压缩成了一个 10bit(LPDDR2/3)/6bit(LPDDR4)/7bit(LPDDR5) 的CA总线。也正因为如此,SoC必须内置复杂的LPDDR协议控制器,把一条读写内存的指令拆解,利用时钟的上升沿和下降沿,分多个周期通过这6根CA总线发送过去。在LPDDR颗粒内部则要有一套解码电路把它还原出来。 下图为DDR3/DDR4的外部接口定义: !image.png 下图为LPDDR4的接口定义: !image.png 通道架构设计不同 此外,LPDDR和DDR这两者在数据传输的底层架构设计上也有着根本差异。 对于标准DDR 来讲,通常采用单通道64-bit的设计(到了DDR5变为双32-bit通道),旨在提供宽阔的单次数据吞吐量。 在PC行业,PC CPU的内存控制器通常是以 64-bit 为基础单元,所以一条DDR4内存条雷打不动就是 64-bit(加上ECC是72-bit)。而在标准DDR的制造体系中,单个内存颗粒(芯片)为了控制成本、封装尺寸和良率,通常不会把数据接口做得非常宽。常见的单颗芯片位宽有三种:4bit,8bit,16bit。主控SoC内部的一个标准DDR控制器,天生就是按照每次吞吐 64-bit 数据来设计的,在这种情况下,就需要把多颗DDR颗粒并联起来使用。 例如,如果使用 8bit 位宽的内存颗粒的话,为了填满 64-bit 通道,我们需要将8 颗内存芯片并联起来(8 bits/颗 × 8颗 = 64 bits)。在PCB布线时,SoC的控制器会同时向这 8 颗芯片发送完全一样的地址和控制命令(比如共享 RAS, CAS, CS)。但是,第一颗芯片负责连接 SoC 的 DQ0~DQ7,第二颗负责连接 DQ8~DQ15……以此类推,第八颗负责连接 DQ56~DQ63。当控制器下达一个读命令时,这 8 颗芯片同时吐出数据,在总线上汇集成 64-bit 的数据流。 !image.png > 当然,在消费类电子和智能硬件主板上,因为这类嵌入式电子产品的应用并不需要太高的内存访问带宽,而更多的物理引脚意味着更大的芯片封装体积、更复杂的PCB布板难度以及更高的功耗。因此,芯片原厂在设计SoC时,会根据芯片需要的带宽量体裁衣:不会直接采用PC领域常见的64bit位宽的数据传输结构,更多的是使用32bit甚至16bit的位宽。 LPDDR则采取了完全不同的数据传输通道的设计架构。为了在低功耗下维持高带宽,采用了多通道、窄位宽的架构。例如,一颗LPDDR4芯片通常由两个独立的16-bit通道组成(共32-bit)。如下图所示,整个LPDDR4芯片内部分为两个完全独立的Channel,内存控制器就可以在同一个时钟周期内,让Channel A去响应NPU的读请求,同时让Channel B去响应CPU的写请求,并发性更好。 !image.png 这种架构允许SoC以更灵活的方式调度内存,降低唤醒整个内存颗粒带来的功耗。例如,如果当前的系统负载很轻,SoC可以完全让Channel B进入深度休眠(Self-Refresh或Power Down),只维持Channel A的运转。 LPDDR的初始化时序问题 如PSRAM和LPDDR是如何降低功耗的?一文所总结的,LPDDR 为了省电,在其内部砍掉了 DLL(延迟锁相环)模块。而针对高频时钟信号对齐问题,它要求主控 SoC 的内存控制器在系统开机时,通过软件算法在 SoC 的LPDDR控制器内部进行主动相位测算和补偿。 - 对于纯 DDR 控制器而言: 控制器会认为对面的内存带有 DLL,所以它在 Bootloader 阶段发送完基本的复位和模式寄存器(MRS)配置后,会理所当然地认为DDR芯片内部已经实现了时钟对齐,可以直接开始高速数据收发。 - 而对于 LPDDR 而言:因为 LPDDR 内部没有 DLL,每次上电以后,它都需要先等 SoC 的LPDDR控制完成复杂的 Link Training(链路训练)算法,由 SoC 主动来探测时钟信号的时延并做相位补偿。 纯 DDR 控制器根本没有实现以上复杂的Link Training 算法(因为标准 DDR 不需要),因此,如果把 LPDDR 颗粒连接到标准DDR控制器上,两者在握手阶段就会崩溃,系统会直接卡死在内存初始化失败的代码段。 供电网络和功耗管理机制不同 DDR和LPDDR在电路的电源树(Power Tree)设计上完全不兼容。 标准DDR通常只需要较少的电源轨(如VDD, VPP)。而LPDDR为了极致的功耗控制,通常需要多组不同的低电压电源(如VDD1, VDD2, VDDQ),且电压往往远低于同时代的标准DDR。 为了对功耗进行更为精细化的控制,LPDDR 规范在内部集成了极其复杂的电源状态机,能够支持深度睡眠(Deep Power Down)、部分阵列自刷新(PASR)等各种高级的低功耗特性,这些都需要SoC通过特定的协议去控制,而标准DDR不支持这些特性。 为什么部分SOC可以同时支持DDR和LPDDR? 基于以上对DDR和LPDDR的差异,在各个维度上所进行的总结,可以得到结论:这两者相互确实是水火不容、完全无法互相替换的。但我们在一些SoC数据手册上,确实又可以看到这些SOC(如下图所示瑞芯微的部分芯片)可以同步支持DDR和LPDDR这两者内存芯片,这又是什么原因呢? !image.png 这是因为,芯片原厂为了能够支持更为广泛的内存选型,以使用更为广泛的行业应用,在SoC内部植入了昂贵且复杂的Combo DDR Controller & PHY(兼容型内存控制器与物理层)。 为了让一颗SoC能够同时支持物理特性天差地别的DDR和LPDDR,芯片内部的Combo设计至少要在以下三个方面做一些针对性的设计: - 针对DDR的逻辑控制层,SoC内部的DDR内存控制器不再是在硬件层面直接写死,而是同时包含了两套完整的协议状态机,可以分别配置为DDR和LPDDR两种模式。 - 在物理接口层方面,为了实现对两个不同电气规范标准的兼容,SoC外部的数据(DQ)和控制引脚背后的I/O Pad(输入输出焊盘)要被设计成极其复杂的组合电路,同时集成了支持标准DDR的高压大驱动管(对应SSTL电平,如1.2V),以及支持LPDDR的低压微驱动管(对应LVSTL电平,如0.6V)。 - 同时,因为两者的引脚定义完全不同,SoC通过引脚超集 (Superset)与内部多路复用的机制,使用同一批引脚输出与外部的DDR/LPDDR芯片进行连接。SoC在封装时,提供的内存引脚数量会按照需求最多的一方(通常是标准DDR)来给,同时在其内部使用复用器(MUX)的方式对某些特定引脚(如CA总线)的功能进行映射。 值得注意的是,尽管SOC的DDR控制可以通过以上的方式实现对DDR和LPDDR的兼容支持,但是在实际的产品设计中,一旦内存的芯片选型确定,Combo PHY以及PCB的设计就一定是在DDR和LPDDR之间二选一排他性的实现。因此,在硬件原理图设计阶段一旦选定了LPDDR4,不仅多余的引脚要悬空,主板的电源树也必须设计为提供 1.1V/0.6V 的多轨电源,且BootROM的启动配置必须拉高/拉低相应的引脚设置主控的DDR控制器为LPDDR4模式。设备做出来之后,也绝对不可能通过刷软件变回DDR4。 参考资料 - ddr - lpddr2 interface differences between different memory controllers? - Electrical Engineering Stack Exchange - 瑞芯微SoC平台DDR适配提速!第十五期:RK3588/RK3588S:LP4/4X、LP5……
一文入门NFC技术
NFC(Near Field Communication,近场通信)是在当今的消费类电子产品中应用非常广泛的高频RFID(射频识别)技术。本文对于该技术相关的基础理论与应用知识进行了较为充分的总结,借此建立对NFC技术的基础性认识。 NFC技术基础及其与RFID的差异比较 NFC 技术规范运行在全球免授权的 13.56 MHz 频段。与蓝牙或Wi-Fi通过主动发射电磁波(远场辐射)来进行通信的技术不同,NFC 采用的是电感耦合(近场原理)方式来交换信息。 > 所谓的电感耦合,可以想象成一个空心变压器:在两者通信过程中,读写器(主设备)的天线线圈产生交变磁场,当标签(从设备)靠近时,其天线线圈会感应出电流,从而不仅能传输数据,甚至还能为无源标签供电。 !image.png 如果只看以上的这个电感耦合的工作原理的话,就会发现NFC技术与普通的RFID,以及汽车电子领域的无钥匙系统RKE/PEPS等系统所采用的通信技术如出一辙。那么具体而言,NFC 在应用中又有哪些比较特殊的地方呢? 可通过以下表格来对三者的技术规格和应用领域进行对比: !f85c44ab-817f-4e3c-ba85-3c6c3e291820.png 具体来讲,区别主要是: - NFC 只工作在13.56MHz频段,而另外两者都有多个频段可选。 - NFC 的通信距离定位小于 10cm(实际产品中为了过认证,通常只做到 1~3 厘米),这种极短的通信距离是刻意为之的物理级安全屏障,它确保每一次数据交换,都必然伴随着用户主观的物理触碰(Tap)动作,可防止被远距离恶意窃听。而传统RFID和汽车PEPS系统的通信距离一般都有十几米乃至几十米。 - NFC 的工作模式更为灵活,可以支持三种工作模式和通信身份转换,而传统的RFID和汽车PEPS系统都是典型的固定读写器与标签(即发射器与接收器)之间的工作关系。 - NFC 的核心应用价值在于可以传输富文本数据,而另外两者的标签里通常只存一串极其简单的 UID(唯一识别码)或几段加密的密钥,只能用于身份比对。 NFC系统架构及其工作模式 在消费电子产品的 PCB 级设计中,一个完整的 NFC 射频前端系统通常包含以下三个核心部分: !image.png - NFC Controller (NFC 控制器 IC): 它内部集成了射频收发器(Transceiver)、调制解调器以及协议处理微控制器。该控制器模块通常通过 I2C 或 SPI 接口与主控(MCU/SOC)通信。高端的 NFC 控制器内部会自带固件,直接输出标准的 NCI(NFC Controller Interface)指令集,这样可以极大减轻主控的底层驱动开发压力。 - EMC 滤波与天线匹配网络 (Matching Network): NFC 芯片输出的信号是方波,包含有大量谐波。因此在硬件调试过程中,需要在芯片 Tx/Rx 引脚和天线之间设计 LC 滤波电路(滤除 13.56 MHz 以外的干扰)以及阻抗匹配网络,确保芯片输出的阻抗与天线的阻抗实现共轭匹配,从而达到最大的能量传输效率。 - NFC 天线 (Antenna): 通常是一圈几匝的电感线圈。在消费类电子中,天线可以是 PCB 上的走线(成本最低,但占用面积大),也可以是 FPC 柔性电路板(常贴在设备机壳内侧),或者定制的铁氧体绕线天线(适用于金属环境)。 现代全功能 NFC 芯片(例如 PN7160 或 ST25R3916)在内部射频架构的设计上是完全对称的,即同时包含发射和接收链路。在具体的通信过程中,它通过底层的开关矩阵和状态机来动态扮演主从角色。 这些全功能 NFC 芯片的射频引脚上,通常包含有两组射频通路: - Tx 路径 (发射端): 内部是一个功率放大器(PA),连接到 VDD_PA 供电。它的任务是驱动外部 LC 谐振天线,向外辐射出 13.56MHz 的交变磁场。 - Rx 路径 (接收端): 内部是一个高灵敏度的检波器和解调器,负责监听天线上的微小电压幅度变化或相位偏移。 因此,如果产品中的 NFC 芯片是这类全功能芯片,也就意味着其硬件射频结构是完整的,可同时具备 Tx(发场)和 Rx(听场)能力。而对于 无源 NFC 标签(如耗材贴纸)这类产品形态而言,其硬件结构就是残缺的。也就是说,它没有内部供电的 Tx PA,只有天线线圈、整流电路(从磁场取电)和一个调节自身阻抗的电子开关,只有 Rx 能力。 NFC的三种通信模式 在系统开发中,NFC 具有以下三种标准的工作模式: !image.png - 读/写模式 (Reader/Writer Mode): 最常见的模式。设备主动产生磁场,去读取或写入一个无源的 NFC 标签(Tag)/智能卡。这种模式下,当前设备的 NFC 芯片开启其内部的 PA,持续通过 Tx 引脚向天线泵入能量,产生稳定的 13.56MHz 磁场。而且在此后的通信过程中,即使是读取信息,设备也要保持 Tx 磁场不断。 - 卡模拟模式 (Card Emulation Mode): 设备表现得像一张标准的非接触式智能卡(如门禁卡、公交卡、银行卡),由外部设备(如闸机)提供磁场。此时设备 NFC 芯片会彻底关闭 Tx PA,不再对外辐射能量,以节省功耗。当闸机的磁场会在卡设备天线上感应出电压。NFC 芯片的能量收集管脚(或专用的唤醒管脚)检测到这个场,唤醒主控。 - 点对点模式 (Peer-to-Peer, P2P Mode): 两个有源的 NFC 设备靠近时,建立双向通信通道进行数据交换(当然,目前在消费类硬件中,较少使用该模式作为核心数据传输通道,多用于握手,例如辅助建立WiFi连接)。两个设备都是 NFC 全功能设备,在两个设备靠近时通过握手协商双方在后续通信中的角色,确定后固定一方为Initiator,另外一方为Target。 那么接下来的问题是:_已知全功能 NFC 的射频链路设计是对称的,且 NFC 有以上三种工作模式,那么对于一个全功能NFC设备而言,它在后续的工作状态中,如何主动或者被动的选择究竟是以以上三种模式中的哪一种模式和哪一种角色来工作呢?_ 答案是:依赖于NFC 的发现循环 (NFC Discovery Loop),以及主控芯片(MCU)的主动配置介入。 对于一个没有被主控端(MCU)强制限定某一特定模式的全功能 NFC 控制器而言,它在通电待机后,会在底层自动跑一个基于时分复用的状态机,这个状态机被称为 Discovery Loop。 大致的工作逻辑就是,这个状态机会在 Poll-Listen-Sleep 这三个状态之间频繁切换,通常一个完整周期在几百毫秒级别。如果在这个状态切换中通过Poll模式检测到无源标签,就会以读写模式工作;如果检测到外部的闸机,就会以卡模拟的模式来工作。 !b78ed372-8f4f-42a0-aac6-cd8a710780cf.png 当然,在实际的产品开发中,这种全开所有模式跑循环的工作模式,既耗电低效,又容易引起不必要的交互冲突。而通常情况下,一个产品中所包含的 NFC 功能的应用场景都是明确的。因此,在进行系统实现时,就应该在系统初始化时,在主控MCU的应用程序中根据产品NFC功能的业务逻辑需求,主动配置好路由表和发现规则,而不是完全没有现在的在后台反复低效轮询。 - 如果产品的NFC功能应用场景主要是读被动的NFC标签,完全不需要被手机、闸机等当成卡片去读的话,就可以直接通过主控MCU和NFC芯片之间的NCI指令,把芯片的 Listen State 和 P2P 模式去掉。此时,芯片的 Discovery 循环里就只剩下 Poll 和 Sleep,变成了一个纯粹的主动读写器。 - 而如果产品的NFC应用场景中,既需要当读卡器(读取用户的实体门禁卡),又需要当做一张卡(让带有 NFC 门禁卡功能的手机碰一下开门)。此时就要保留完整的 Discovery Loop。 但无论如何,在电池供电的电子产品中,为了极致省电,Poll 状态通常会被替换为 LPCD (Low Power Card Detection,低功耗卡片检测)。 在这个LPCD状态下,设备的 Rx 不再发送完整的协议包,而是每隔几百毫秒发一个极短的脉冲场,仅仅检测天线的电感量有没有发生微小的偏移(因为金属或卡片靠近会导致天线失谐)。如果检测到失谐,才真正唤醒去执行完整的 Poll 过程。这样的话,只有当有人将卡片实际贴到天线上引起电感失谐时,芯片才会被真正唤醒去发场,能将待机功耗从数十毫安降至微安级别。 什么是NCI指令集? 以上提到,部分高端的 NFC 控制器在其内部会运行一个固件,可支持标准的NCI(NFC Controller Interface)指令集,在 NFC 的工作模式设置时,主控MCU就是通过 I2C 或者 SPI 等硬件接口,向 NFC 芯片发出NCI指令来与NFC芯片进行交互。那么这个NCI指令集究竟是什么呢? 在没有 NCI(NFC Controller Interface,NFC 控制器接口)指令集标准之前,各家 NFC 芯片厂商的底层寄存器和控制逻辑五花八门,软件工程师如果想换一颗 NFC 芯片,几乎要把整个驱动层重写一遍。针对这个问题,NFC Forum 制定了 NCI 标准,目的就是彻底屏蔽底层射频时序和物理链路的复杂性。 在 NCI 指令集的加持下,主控处理器只需要通过 I2C 或 SPI 向 NFC 芯片发送标准化的 NCI 字节流,芯片就会自动去处理那些复杂的射频唤醒、冲突检测和底层协议校验方面的事情。这样的话,如果后续在产品的开发过程中,要更换NFC芯片的话,只要换一个同样支持NCI指令集的NFC芯片就好,主控端的驱动层和应用层几乎不需要做任何改动。(当然,现实中没有这么理想,一些厂家会在NCI指令的框架基础上增加一些自定义指令,这部分就需要额外调试) NCI 规范把在物理总线(如 I2C,SPI)上传输的数据包(Packet)严格划分为四种类型: - CMD (Command - 控制指令): 主控 (MCU/SoC) NFC 芯片,是主控下发的动作指令。 - RSP (Response - 指令响应): NFC 芯片 主控,针对 CMD 的同步应答,芯片在收到 CMD 后必须在极短的时间内回复 RSP。 - NTF (Notification - 异步通知): NFC 芯片 主控。芯片主动上报的异步事件。 - DATA (数据包): 双向,纯粹的业务层数据透传。当底层连接建立后,主控和卡片/外部设备之间读写的真实数据(如 NDEF 富文本、URL)都会被封装在 DATA 包中。 !image.png 在软件研发阶段,NCI 的标准化特性为团队分工带来了极大的便利: - BSP / 驱动层:驱动工程师不需要懂任何 NFC 协议栈的逻辑,只需要在 Linux/RTOS 中调通 I2C 或 SPI 接口,并配置好一个 GPIO 中断引脚(用于 NFC 芯片向主控发送 NTF 通知时触发中断)。在 Linux 系统下,这通常体现为一个简单的字符设备节点(如 /dev/pn544 或通过 I2C 核心层注册的设备),这个节点的唯一作用就是透明传输 NCI 字节流。 - 协议栈 (中间件):NCI 报文的解析和组装由中间件完成。 NXP 提供了基于 Linux 的 libnfc-nci 库。如果是 Android 系统,AOSP 源码中的 system/nfc 已经内建了极其完善的 NCI 协议栈。 - Linux 应用层 / APP :应用层开发人员直接调用协议栈/中间件暴露出来的上层 API 即可,比如 nfc_enable()、nfc_read_ndef() 等等。 MIFARE/FELICA/IEC14443 在 NFC 标准确立之前,各家芯片大厂在 13.56MHz 的高频 RFID 领域,都提出来自己的底层调制方式和私有数据格式。后来,NFC Forum 成立,它的伟大之处不在于发明了一种全新的射频技术,而是向下兼容了这些大厂所推出的私有解决方案,并向上统合成了标准的 NDEF 数据格式。 在这个领域,NFC 针对以下五个主流技术流派提供了兼容性的支持: - MIFARE:由 NXP 主导,是目前全球普及率最高的非接触式智能卡技术,它底层主要基于 ISO/IEC 14443 Type A 射频标准。应用非常广泛,小区门禁卡、酒店房卡、交通卡、一次性纸质门票/贴纸用的都是这种技术。 - FeliCa :是由 Sony 研发的独立标准,对应于日本工业标准 JIS X 6319-4。日本的 Suica(西瓜卡)、香港的八达通(Octopus)是它的绝对主场。 - ISO/IEC 14443 Type B:当年制定 14443 标准时,NXP 主导了 Type A,而意法半导体(ST)、摩托罗拉等联合主导了 Type B,更适合处理高密度的加密运算。 国内的第二代居民身份证、各种接触/非接触式银行卡(EMV 标准)、电子护照等,几乎清一色采用 Type B 标准。 - ISO/IEC 15693:相比前几种技术,牺牲了通信速率,换取了更远的读写距离,读写距离可以达到 几十厘米,且支持多标签同时快速防碰撞读取。典型应用是图书馆自助借还书系统、滑雪场非接触式雪票、医用试剂盒的批量盘点。 !image.png 面对市场上非接触卡的这么多种五花八门的底层芯片,如果我们要对这些卡进行扫描,Linux 应用层或 APP 开发团队如果直接去解析它们底层的扇区(Sector)或块(Block),面对的兼容性问题会非常棘手。 对此,NFC Forum 定义了 Type 1 到 Type 5 五种标准的“NFC Tag Types”,强制将上述底层硬件进行了抽象映射。只要底层芯片符合这些 Type,主控抓取上来的就都是结构化的标准富文本数据,开发团队直接在 Cloud 或 APP 层解析标准负载即可,这样就实现了业务层与物理卡片的解耦,这些不同的卡标准的兼容性问题就迎刃而解了: - Type 1: 基于老式的 Innovision Topaz。 - Type 2: 完美映射 MIFARE Ultralight 及 NXP NTAG 系列。 - Type 3: 完美映射 Sony FeliCa。 - Type 4: 映射 ISO 14443 A/B(涵盖了 DESFire 和 CPU 卡)。 - Type 5: 映射 ISO 15693。 参考资料 - https://www.cnblogs.com/bluestorm/p/17705366.html - https://www.sony.co.jp/en/Products/felica/NFC/forum.html - 【NFC原理】学会这些知识,你也可以成为NFC领域的小专家!
电子产品的工作温度以及芯片热阻结温等的计算过程总结
本文针对电子产品中常见的热设计方面的问题,对元器件数据手册中提供的温度、热阻等参数以及利用这些参数进行内部结温的计算流程进行了详细整理,为后续进行电子产品硬件系统设计、芯片选型以及热设计参数的测试和估算提供理论基础。 元器件数据手册上的温度参数 一般而言,在进行消费类电子产品的设计过程中,我们所遇到的芯片数据手册上与温度和热设计相关的参数主要是芯片工作的环境温度 和结温 。 其中的 (Ambient Temperature, 环境温度) 是指芯片(或设备)在正常上电工作的过程中,紧贴着其外壳周边的空气温度。需要注意的是,产品PRD上定义的设备环境工作温度与芯片数据手册里的环境温度完全不是一回事。 实际上一般而言,产品规格书中所定义的环境工作温度,是产品外壳外面的空气环境温度。而当我们把发热的 SoC、电源和 Sensor 塞进一个密闭的塑料外壳以后,由于电路板上所有元器件工作过程中发热所带来的温升效应,紧贴着芯片周边的机壳内部环境温度很有可能比机壳外部的空气温度高十几度甚至更高。 下图演示了设备外部环境温度 与设备内部环境温度 之间的巨大差异,而对于芯片本身来讲,它更关注的自然是芯片内部的环境温度: !59932155-22a6-4ad0-9589-2937dbbb5cdf.png 而 (Junction Temperature, 结温) 是指在半导体芯片内部,真正的硅晶圆(Die)上产生热量的 PN 结(晶体管,结温实际上就是PN结的温度)的物理工作温度。结温 是电子产品中一切热设计的根本标准,芯片是否能稳定工作、寿命长短、是否会烧毁,全部由 决定。只要 没有超标,外部环境怎么恶劣都没关系。当然,因为 PN 结是在芯片内部,所以芯片内部的结温我们测试无法测试到的。 除了以上的环境温度 和结温 以外,数据手册上所包含的温度相关的参数还有: - (Case Temperature, 外壳/表面温度):芯片封装外壳正中心表面的温度。部分芯片的数据手册中会明确给出芯片封装的最高外壳温度()这个参数,这样可以简化热设计,我们就可以不必去反推结温了,只要保证芯片封装外壳中心表面的温度低于这个参数即可。但绝大多数芯片的数据手册,都不会提供这个 ,只会给出一个结温的最高限制。 - 存储温度:芯片在不通电的状态下,可以安全长期存放的温度范围。这个温度范围通常非常宽,消费级芯片一般为 -65°C 到 +150°C。这个参数主要是给供应链和物流环节看的。芯片以及产品的物流运输过程中,只要不超过存储温度的上限,芯片的封装材料就不会发生不可逆的物理膨胀破裂,其内部的键合线就不会断。 - 焊接/回流焊温度:芯片在 SMT(表面贴装)等工艺中,过回流焊炉时能够承受的极限峰值温度和时间。典型参数通常是 260°C,持续 10 秒(符合无铅 RoHS 标准)。这个参数主要是给工厂 PE 看的,生产焊接过程中的回流焊炉温曲线应按照这个参数进行设置。 几个容易混淆的热阻参数 除了以上的通用温度参数以外,大部分对热设计敏感的芯片数据手册中,往往还会提供以下几个热设计相关的热阻参数,以方便开发人员在设计和测试过程中准确的计算功耗与热相关的数据。 (Junction-to-ambient thermal resistance / 结到环境热阻):该参数对应于热量从晶圆PN结区产生,穿透封装、PCB,最后散发到周围空气中的总热阻。看起来使用这个参数可以方便的从芯片表面温度计算出来结温,但是这个数值是原厂在一块面积巨大、没有外壳遮挡的 JEDEC 标准测试板上,放在一个体积为 1 立方米的密闭无风静压箱里测出来的。而我们的产品一般内部空间狭小且有其他热源相互叠加,热环境完全不同。因此如果在工程计算中直接套用这个值,算出来的结温会有非常大的偏差。 (Junction-to-case (top) thermal resistance / 结到顶部外壳热阻):该参数纯粹描述了热量从结区垂直向上穿透封装盖板到达最顶层表面的物理阻力。它的计算公式是: 这里的 是仅向芯片内部通过顶部封装散发出去的热量。问题是我们只能准确的计算出来整个芯片的功耗,至于整体的功耗有多少比例是向上散热的没办法预估,所以这个参数在实际的运算中并不实用。 和 (结到板热阻 / 结到晶圆底部热阻): 该参数与 相对,描述的是热量向下穿透硅基底传导到 PCB 或封装底部的物理阻力。同样的问题是,我们也没法准确的预估芯片的功耗有多大比例是向下去散热的。 (Junction-to-top characterization parameter / 结到顶部热特性参数):这个参数表示在标准的自然对流的测试环境中,结温与表面中心温度之差,与芯片总输入功耗的比值,其计算公式为: 与 相比, 是指整个芯片的完整功耗,可以通过示波器或者万用表测试得非常精确,所以使用 参数与芯片表面中心点的实测温度来计算结温,能够更准确的反映出来芯片内部的实际结温。 !image.png (Junction-to-board characterization parameter / 结到板热特性参数):与 的概念相对应,是指结温与距离芯片边缘 1mm 处 PCB 覆铜温度之差,与芯片总功耗的比值。利用这个参数可以通过测量芯片底部边缘覆铜(在某些情况下,例如对sensor模块)的温度来计算芯片内部的结温。 所以总的来讲,带有 符号的几个参数(如 、),在实际进行结温的计算时都不是很实用。主要是因为芯片运行过程中所产生的总热量(总功耗 )是兵分多路的:一部分热量向下通过引脚和焊球传导到了 PCB 覆铜上( ),其他的热量向上穿透塑封体散发到空气或外壳中( )。问题是我们根本无法准确地测量出到底有多少比例的功耗是往上走的。因此,即便原厂给出了精准的 ,我们也无法准确算出真正地结温 。 理想情况下的温度计算理论与流程 那么在工程实践中,我们如何通过测试和计算的手段,验证当前的设计是否能够符合项目和产品的温度要求? 如上所述,芯片内部的结温 是评估产品热设计的根本标准,只要通过测试和计算出来的结温符合芯片数据手册中的结温要求,那么这个产品从设计的角度上就是合格的。 而对芯片内部结温的计算和评估,大致有以下三种情况。 第一种情况,芯片的数据手册中给出了芯片封装外壳正中心表面的温度参数 。因为绝大多数芯片内部的裸片(Die)都是居中贴装的,发热核心就在芯片封装的正下方。热量呈倒漏斗状向上传导,所以封装表面的正中心,就是整个可接触外壳上温度最高的热点。 在这种情况,我们就不需要使用复杂的热特性参数()或去反推结温()了,可以直接用热电偶测出芯片表面的中心温度,然后拿测试值跟芯片数据手册中所定义阈值进行简单的比对即可。 因此,在芯片数据手册中提供了 参数的情况下,这就是硬件和结构工程师在实际工作中最喜欢、也最高效的判定方式。但行业现实是:绝大多数消费级或安防级的 SOC和 Image Sensor,其数据手册里大概率是不会给出 的,只给 或 。 第二种情况,很多复杂的大型芯片在设计之初,为了实现自我保护,会在 Die 的发热核心区域(比如 CPU/NPU cluster 旁边)直接刻蚀一个热敏二极管用于测量其内部的结温。 例如,对于部分主控 SoC ,其内部通常自带 TSADC(温度传感器),因此可以直接通过软件读取寄存器或 Linux 下的 sysfs 节点(如 /sys/class/thermal/thermal_zone*/temp)来实时其获取核心的结温。通过这种方式读取到的结温也是最准确的。 这种方法虽然最准,但在大部分面向消费类电子的低成本芯片上往往行不通。因为绝大多数消费级芯片的内部是不带温度传感器的。 在前两种情况都无法实现的情况下,通过热电偶来测试芯片外部表面的温度,然后通过热阻(Thermal Resistance)参数来反算内部结温的方式,这成为硬件和热设计工程师最标准的做法和流程。 该流程最关键的计算公式为: 其中: - (Junction Temperature):我们要计算的目标结温。 - (Case Temperature):芯片封装正上方表面的中心温度。 - (Power): 芯片当前的实际运行功耗(单位:瓦特)。 - (Psi-JT, Junction-to-Top Characterization Parameter): 结到封装顶部的热特性参数(单位:°C/W)。 以上方法的实验室操作步骤如下: 1. 首先测试 (即芯片表面正中心温度): 推荐使用 K型热电偶(建议 36 AWG 或更细),配合高导热胶,将热电偶牢牢粘在芯片封装表面的正中心位置。然后将整机放入高低温箱,设定产品PRD定义的最高环境温度烤机,待温度曲线平稳后,通过数据记录仪读出 。 2. 测试该芯片对应的动态功耗 :在高温环境下,半导体的漏电流会变大,功耗会上升,因此不能直接用 Datasheet 里的标称功耗。此时需要用示波器或高精度万用表,实测 Sensor 各路电源(AVDD, DOVDD, DVDD)在高温满载工作下的实际电流和电压,计算出真实总功耗 。 3. 按照上面的公式推算出 : 将测得的 、实际功耗 和原厂给定的 代入公式,即可准确得出当前环境下的内部结温。 下面以TI的3D ToF Sensor OTP8241为例对以上计算流程进行说明,该传感器的 参数为6.3度/W: !649c01a3-5675-44b4-91d3-e56c3e45ee5d.png 假设在 70°C 的高低温箱里进行极限烤机,用热电偶测得这颗 Sensor 封装正中心表面的温度 达到了 85 °C,用示波器实测它在当前帧率下所有供电轨的总功耗 是 1.2 W。那么它内部真正在经受考验的真实结温就是: 以上就是在理想情况下,对于芯片内部的结温进行相对比较准确的测试、估算以及最终评估产品热设计稳定性和合理性的计算流程。 但是在现实的产品设计中,很多消费级或安防级低成本低价格 SOC 和 Image Sensor,原厂在研发定型时往往只会做基础的高低温工作范围测试(比如标定极限工作结温 在 -30°C ~ 85°C),并不会严格按照 JEDEC 标准去出具完整的三维热阻矩阵(, , )。 所以,在这类低成本消费类芯片的数据手册中,根本就找不到 这个参数,所以也就没法按照上面的流程和公式精确的计算其内部结温了。这种情况下,我们就只能采用估算的方式大致评估设计是否合理和满足要求。 现实设计过程中的估算 如上所述,如果芯片的数据手册没有提供出来准确的 参数,我们实际上是没有办法精确地计算出来结温。这种情况下就只能通过一些经验值的估算来大致评估整个产品热设计的合理性和风险系数。 在实际产品的工程设计中,最常用的办法就是使用我们能够测试到的芯片表面温度 来大致的估算与其对应的结温 。如何通过 来相对比较准确的估算出来 ,与芯片所采用的封装形式密切相关。 FCBGA/Bare Die: 这类封装主要为大算力、高发热而生,硅片在封装中被倒扣在基板上(Flip-Chip),因此其发热核心直接顶着最上方的金属散热封装盖板(Lid)或者干脆裸露出来。这种情况下,芯片内部 PN 结的热量的散发形式是绝对的向上散热。这种情况下 经验值为 0.1 ~ 1.0 °C/W,这意味着芯片内部的结温 几乎等于表面温度 。 QFN / DFN / ePAD-SOIC:这类封装在芯片底部有一片金属裸铜,直接焊在 PCB 的地线上,多见于电源管理芯片(PMIC)、电机驱动、大功率音频功放(Audio Amplifier)。因此其散热方向是绝对的向下散热。但因为这种封装的顶部塑封材料通常打得很薄,硅片距离顶部的物理距离极短,所以它向上的 依然很小。 的经验值为 0.5 ~ 4.0 °C/W。 QFP / LQFP / TQFP:这类封装四边有鸥翼型引脚,黑色的塑封体比较宽大且有一定的厚度。大多数常规的 MCU(单片机)、接口控制芯片(如 USB/以太网 PHY)通常采用这种封装。散热方向四通八达,一部分通过引脚往下走,一部分通过塑料外壳往上散。 经验值一般在 2.0 ~ 8.0 °C/W 之间。 SOIC / TSSOP:这种封装两侧有引脚,封装体积相对于内部那颗极其微小的 Die 来说显得比较厚重,多见于常规的逻辑门电路、运放、音频 ADC/DAC 或基础的小电流模拟芯片。其散热方向主要是通过引脚传导热量。因此,对于这类封装而言,塑料外壳本身的超高热阻成为了阻碍,导致表面的温度 会比内部的 低非常多, 经验值一般在 5.0 ~ 15.0 °C/W。但好在这类芯片通常功耗极低(毫瓦级),基本不会面临严苛的散热危机。 参考资料 - Thermal Resistance Data: Definitions of Thermal Resistance, Thermal Characterization Parameters | About Thermal Design | TechWeb
如何理解和应用AI-DLC的开发理念?
很多开发者在使用 Claude Code、Trae 或 Cursor 这类AI开发工具辅助开发时,往往会陷入随性编码(即所谓的Vibe Coding)的陷阱:想到什么,就编写一段简单的提示词让 AI 写什么。这种方式在写功能简单的小应用程序、脚本文件等效率很高,但在面对比较复杂的中大型项目时,很快就会导致代码库混乱、上下文丢失和极高的维护成本。针对以上问题, AWS 在 2025 年初提出并开源了一个核心方法论:AI-DLC(AI-Driven Development Life Cycle,AI 驱动的开发生命周期)。 AI-DLC的概念 在传统的软件开发流程中,整个开发流程的框架总体是由人类驱动的,产品所有者、开发人员、架构师都要将大部分时间花在一些非核心活动上,比如计划、会议和其他软件开发生命周期的事情上,也就是所谓的SDLC(Software Development Life Cycle)。 生成式人工智能技术兴起以后,这类AGI的工具在理解语义、阅读和编写代码的技术与质量得到了突飞猛进的进步,但是如果只是把 AI 当做辅助自动补全和生成代码的局部开发工具,既无法发挥不出来 AI 所具备的强大语义理解和生成的能力,而且容易陷入局部困境,无法适应中大型项目的开发需求。 在这种情况下,ASW 提出了一个针对 AI 时代重构整个软件开发流程和职责的方法论,这就是AI-DLC。这个方法论的核心思想是:在软件开发流程中,重新定义 AI 和人类之间的合作关系,由人类制定判断标准并进行决策,AI 负责流程的编排、执行和自我验证(Humans codify the judgement. AI orchestrates and self-verifies)。 可以通过下表的对比来直观理解软件开发流程在AI时代的范式转变: !AI_DLC_Comparison_Table.png 可以从以下两个维度来理解 AI-DLC的总体逻辑: - 在人工监督下的 AI 驱动执行流程:针对具体的开发需求,由人工智能系统地创建详细的工作计划和流程,并与在人工配合的过程中积极寻求澄清和指导,并将关键决策步骤交由人工判定。这一点至关重要,因为只有人类拥有做出明智选择所需的上下文理解和业务需求知识,AI 工具需要在人工指导和判断的框架下进行工作,而非自行随意发挥。一旦需求澄清和执行方案确认,后续的执行过程完全依赖 AI 工具完成,人工在旁监督即可。 - 动态团队协作:AI 在安装确定的方案执行任务过程中,由人和 AI 所组成的团队在协作空间中团结起来,实时解决问题、进行创造性思维和快速决策。这种从孤立工作到高能量团队合作的转变加速了创新和交付。 AI-DLC的工作流程 总体上,AI-DLC 的开发理念按照如下流程工作:AI 负责按照项目需求制定工作计划,在制定计划的过程中针对需求和技术方案的模糊点向人类提出明确的问题,以寻求更多的上下文和背景信息,最终确定的技术执行方案和行动计划在接受人类验证后开始实施和执行。 !image.png 按照以上整体的理念和流程,AI-DLC 并不是让 AI 在拿到需求以后直接开始写代码,而是强制 AI Agent 遵循一套极其严谨的工程化阶段。它将开发流程分为以下三大核心 Phase。 阶段一:Inception 这个阶段负责澄清需求,制定计划与执行步骤,即解决解决“做什么”和“为什么做”的问题。 该阶段要执行的任务包括: - 工作区检测与逆向工程 (Workspace Detection & Reverse Engineering): AI 首先会扫描现有的代码库,理解当前的架构、技术栈和已有业务逻辑代码。 - 需求分析与用户故事 (Requirements Analysis & User Stories): AI 通过提问并得到明确的答复来澄清模糊的需求,并将其拆解为标准的用户故事(User Stories)。 - 系统设计与工作流规划 (Application Design & Workflow Planning): 确定系统的整体设计架构后,AI 负责将大任务拆分成一个个独立、可并行或串行执行的“工作单元(Units)”。 阶段二:Construction 在此阶段,AI 开始按照 Inception 阶段所制定的计划,逐个处理工作单元(Units)。针对每一个单元,AI 会循环执行以下步骤: - 详细设计: 包括功能设计(代码逻辑)、非功能设计(安全性、性能考量)和基础设施设计。 - 代码生成与测试驱动: AI-DLC 强烈要求代码与测试用例必须同步生成,适应测试驱动开发模式可以有效提升开发质量的管控。 - 自我构建与验证: AI 会尝试跑通构建和并自行执行测试用例,如果报错,它会根据错误日志进行自我修复。 阶段三:Operations 这个步骤是项目开发完成后的上线运维和监控步骤,主要包含开发完成后代码的部署、持续集成以及上线后的监控。AI 同样在这个流程之中协助排查日志、生成运维报告并持续优化。 以上的每个阶段,实际上都可以为下一个阶段的执行提供了更丰富的背景和上下文,从而使 AI 能够提供越来越明智的建议和执行结果。 !image.png AI-DLC理念与最新AI开发工具的对比 以上基于对AWS AI-DLC开发理念白皮书及其相关技术文档的学习,整理了该开发流程和理念的相关理论知识。 但是实际上站在今天(2026年6月)的角度回溯,其实会发现这个AI-DLC的概念并没有什么出奇之处。因为我们现在使用的大多数主流AI开发工具(如Antigravity 2.0、Claude Code、Codex等)在其底层架构设计上已经天然固化并强制执行了以上所描述的核心开发流程和规则。 例如,在使用Google的Antigravity 2.0进行软件开发时,我在一个项目中提出一个开发需求,实际上Antigravity 2.0本身就会在修改任何代码之前首先分析我提出的需求,针对其中的模糊点提出确认,并制定一份implementation plan文档,我确认这个执行计划以后,Antigravity 2.0 就开始执行,并且在执行过程中有必要时申请权限和确认中间步骤,最后在开发完成后还会通过一个walk through的文档总结完整的执行过程。所以以上的这个自动化的过程已经完美的覆盖了AI-DLC的开发理念,而且这还只是Antigravity这类工具的开箱即用的特性而已。 但放在2025年3月份的这个时间节点,在 AI 开发工具的主流还无法应对中大型项目的开发时,AI-DLC 的提出还是很有其价值和应用前景的。而 AI 软件开发工具在2025年后半年在应对中大型项目的开发能力得以突飞猛进,也是因为整个 AI 软件工程界在经历了 2023-2024 年散装 Prompt和盲目写代码导致上下文崩溃的经验教训后,共同走向了使用更规范的流程化的思路来提升 AI 代码质量的殊途同归之路。 以下是 AI-DLC 的开发理念与当前Antigravity 2.0实现的应对与对比: !AIDLC_Workflow_Mapping_20260612.png AI-DLC 理念的价值所在 那么放在2026年的今天来看,在AI开发工具已经越发先进和规范的情况,AI-DLC 及其相关的开发规则和流程还有价值吗? 我认为,无论开发工具如何演化,至少在以下两个方面,这类开发规则依然应该得到重视。 统一团队的开发规则和规范 在团队开发中,不同的开发人员有自己的开发工具偏好,有人习惯用 Trae,有人用 Claude Code,还有人固守 Cursor。不同工具的底层行为差异会导致团队开发代码质量参差不齐。 那么,我们可以定义一套通行于团队内部的类似 aidlc-workflows 这样的显式规则(如 .cursorrules 或全局系统 Prompt),在团队内部就可以跨工具统一 AI 的行为。不管开发人员用什么工具,只要加载了这套统一的开发规则(Rules),AI 都会被迫先写设计文档、先写单元测试,从而实现工程质量的标准化。 !90409f5b-722a-4711-929e-c413f8e3f01e.png Rules 可应对更复杂的多 Agent 协同场景 当前的 Antigravity 2.0 这类开发工具即使到了今天,也依然偏向于使用一个强大的 Agent 解决一个具体 issue 的开发场景。但当我们要面对超大型项目开发和重构时,往往需要产品 Agent、架构 Agent、编码 Agent、测试 Agent 来协同工作。AWS 所提出的这套自适应路由规则(Adaptive Workflow Steering),本质上是为了未来的多 Agent 编排(Multi-Agent Orchestration)搭建的理论框架,不同的 Agent 对应于自己的 Rules,使之工作流程更符合自身角色定义的要求,从而提升各个Agent各自的开发质量。 参考资料 - AI-Driven Development Life Cycle: Reimagining Software Engineering | AWS DevOps & Developer Productivity Blog
Amazon AWS之Cloudfront Service学习总结
Cloudfront的工作流程 Amazon CloudFront Service的定位是 AWS 的全球内容分发网络(CDN)服务(目前已经在所有的AWS Region中处于全面可用/GA状态)。它的核心作用主要是缓存静态资源,通过 AWS 在全球部署的骨干网加速静态以及动态内容的传输与发布。 CloudFront Service的网络底层基于AWS部署的数百个遍布全球的 POP(边缘节点)。这种情况下,当用户或设备向其发起网络请求时,流量会被AWS Anycast 路由到其物理距离最近的节点,极大的加速静态和动态内容的传输。 以下使用一个从 AWS 东京Region的S3 Bucket中通过Cloudfront service下载文件的流程图,来对Cloudfront Service的工作流程进行解释。 终端用户每次向Cloudfront的URL发起请求,该请求首先会被AWS Anycast路由到距离请求发起方最近的Cloudfront网络节点。然后Cloudfront会去检查是否缓存命中(即CloudFront自身的缓存是否包含请求所需要的静态资源文件): - 在缓存命中,即CloudFront缓存包含有请求所需要的文件时,直接跳转到第四步,返回该文件给终端用户。 - 而如果缓存未命中,CloudFront会通过AWS在全球部署的骨干网络向部署在S3东京站的bucket发起回源请求,从S3 Bucket中读取该文件到CloudFront的缓存中,把这个文件返回给终端用户,同时保存在CloudFront的缓存中,这样后续再次访问的时候就可以缓存命中,直接从缓存中向终端用户返回文件。 !35808f53-88a2-425a-b6a0-4085d1b8d8ff.png 由以上流程可以看到,Cloudfront 作为AWS的CDN服务最主要的作用就是:可以实现静态资源文件(尤其是热点资源)的全球网络加速分发服务。热点资源在短时间内请求数量很多,使用CDN服务可以利用其分布在不同地理节点的缓存服务器把资源快速的分发给距离最近的用户终端,既有效的提升了用户体验,而且也避免了所有用户请求集中到同一节点所带来的稳定性和网络路由低效的问题。 即便是针对缓存未命中的动态资源,因为CND缓存服务器(CloudFront)与动态资源实际存储的回源服务器(如以上的东京Region的S3 Bucket)之间走AWS的内部骨干网络,相比用户直接访问回源服务器,用户请求响应的速度也得到很大程度的提升。 CloudFront是如何管理缓存的? CloudFront 不限制存储在其边缘站点的单个文件(对象)的大小,因此可以缓存从几 KB 的脚本文件到几十 GB 的软件安装包。 AWS 拥有遍布全球的多个边缘站点,每个站点都有其特定的硬件存储容量方面的限制,CloudFront 当然不可能在其缓存服务器中一直保存之前访问的缓存文件。 通常情况下,CloudFront 使用最少使用(LRU - Least Recently Used)的算法来动态管理其缓存服务器中所保存的文件。如果一个文件在某个边缘站点存储时间很长且很少被访问,当前存储空间不足时,它就可能会被删除以腾出空间。这样的话,下次对这个文件发起的新请求又会被转发到回源服务器请求数据。 当然除了以上的 LRU 算法以外,缓存是否失效也与文件自己设置的 TTL 生命周期时长有关。 缓存时间限制TTL 文件在 Cloudfront 缓存中的有效时间也可以通过源站点的 TTL 参数来进行设置。 默认情况下,CloudFront 会遵循源站点(如 S3、EC2 或 API Gateway)返回的 HTTP 缓存标头参数Cache-Control: max-age=和Expires: 来设置该文件在缓存中的有效时间。 因此,如果我们对于文件的时间有效性有特定的要求,可以在源站服务器配置或 S3 对象元数据中设置这些标头信息,以更精细地控制每个文件的缓存时间。 高 TTL (缓存时间长): - 优点:可增加缓存命中率。文件在边缘站点保留时间长,意味着当用户请求时,更有可能从边缘站点直接服务,从而大幅减少回源请求,这就减少了从源站到 CloudFront 的数据传输费用。 - 缺点:内容更新较慢,用户请求到的文件可能是过期的,因此如果对于文件本身的生命周期有较高要求,不应设置过高的TTL。 低 TTL (缓存时间短) 或 0 TTL (不缓存): - 优点:每次请求得到的数据文件的内容都是最新的。 - 缺点(更贵): 会降低缓存命中率,这样大量用户请求会到回源服务器请求数据,请求数量和费用增加。 因此,究竟应该要设置高还是低 TTL 参数,要根据自己文件和应用的设计需求来定:如果对数据文件内容的时效性要求比较高,就应该选择低TTL,代价就是费用会较高,否则就应该选择高TTL的设置,尽可能减少回源请求的次数。 Cloudfront的费用模型 以下通过从S3上下载文件的典型应用对比增加CloudFront的情况下,对于云服务使用成本的影响。 总体来讲,对从S3上下载文件的这个流程,与云服务使用成本费用相关的部分主要包含:存储、出向流量、请求(API/HTTP)。 - 存储 (Storage):即 S3 上的静态对象存储费,按存储在 S3 中的数据量 (GB/月) 计费。Standard 存储类前 50 TB:0.09 / GB。 - Cloudfront 下载模式,按地区+阶梯计费。北美/欧洲环境中的费用为 0.0004 / 1,000次请求。 - CloudFront 模式下,如果缓存未命中,从 Cloudfront 向 S3发出的 API 请求费与以上相同。因此这部分费用与缓存命中的比例相关。高命中率下这项费用趋近于 0。 - CF HTTP/HTTPS 请求费:按用户发送给 CloudFront 边缘节点的请求次数计费。HTTPS 请求在北美的费用为 0.0004 / 1,000次请求。 - 而通过Cloudfront下载,这部分费用包含两个部分,一个是用户发起的Cloudfront API的请求费用,费率15 固定费用的 Pro 用户为例,该套餐包种包含的免费额度包括: - 出向数据流量传输 : 高达 50 TB,这部分按照传统按需模式下的价值约 $4000+。 - 访问请求数: 10,000,000 次(1000 万次)。 - 增值安全 (免费送): 强制开启并包含 AWS WAF(Web 应用防火墙),自带 25 条规则,并包含 DDoS 保护。 - S3 存储抵扣: 每月额外赠送 50 GB 的 Amazon S3 标准存储额度。 !ae7f5972-7413-4337-8b34-9eb8adfd1f54.png 在这个固定费率方案的加持下,使用CloudFront的费用成本将会大幅度降低,以下是一个S3存储容量1TB,每月出站流量10TB,请求数量1000万次,缓存命中率90%的情况下,对比直接访问S3、通过CloudFront访问S3(标准费率模式)、通过CloudFront访问S3(固定费率模式)这三种情况下的费用状况对比: !21d886b9-5247-41e0-b905-17fc1aed910a.png 参考资料 - https://aws.amazon.com/cn/s3/pricing/ - Amazon CloudFront CDN — 计划和定价 — 免费试用 - CloudFront 固定费率定价方案 - Amazon CloudFront
模型FP16和INT8量化的计算流程总结
本文对Pytorch等模型训练框架训练出来的模型,进行浮点半精度转换FP16和定点量化INT8的相关概念和计算流程进行完整的总结。 Pytorch 模型的训练与存储格式 在我们常见的 PyTorch、TensorFlow 等主流深度学习框架中,默认使用的张量(Tensor)数据类型是FP32 (32-bit floating point, 单精度浮点数)。因此,我们在 PyTorch 中定义一个卷积层 nn.Conv2d 或线性层 nn.Linear 的时候,框架所提供的随机初始化的权重参数(Weights)、偏置(Biases),以及在前向传播时所产生的激活值(Activations)等,默认全部占用 32 个比特(即4 字节,FP32)的内存空间。 当我们在 Pytorch 中完成模型训练,使用 torch.save() 保存模型文件到本地硬盘。由于训练过程中默认的张量 dtype 类型是 FP32,所以通过这个标准流程保存的模型也就是 FP32 的。 但是为什么我们从 Ultralytics 上下载的官方 YOLO 预训练模型文件,其模型文件大小对应的内部参数是FP16,而不是FP32呢? 这是因为,Ultralytics 官方所提供的 YOLO 预训练模型文件(如 yolov8n.pt 或 yolov5s.pt)在发布前,都会被强制转换成了 FP16 格式,其核心目的是为了大幅节省传输带宽和存储空间。 Ultralytics 在模型训练完成后,会调用他们内部一个极其经典的后处理函数:strip_optimizer()。这个函数会调用模型 .half() 将其权重全部转为 16 位半精度浮点数 FP16 格式。大概的流程如下: FP16半精度转换的计算过程 从严格意义上讲,把模型参数的存储格式由 FP32 转换到 FP16 的过程称为类型转换(Type Casting / Downcasting),而不是严格意义上的量化(Quantization)。 要理解这个转换过程,必须要先理解FP16和FP32这两个数据类型在内存中的真实面貌。这两种浮点类型的数据在内存中的形态符合IEEE 754 浮点数二进制标准。 IEEE 574 规范采用科学计数法(例如 可以写成 )在内存中表征浮点数据。该规范将浮点数的表示分为三个区域:符号位 (Sign)、指数位 (Exponent) 和 尾数位/小数位 (Mantissa/Fraction)。其最终还原的统一数学公式为: 其中: - 符号位 S :永远是最高位(第 1 位),规则为用 0 代表正数,1 代表负数。 - 指数位 E:紧随符号位之后,用于控制数字的大小和动态范围。 - 尾数位 M:用于控制数字的精度和有效数字的位数。在规范的二进制科学记数法中,数字小数点前永远是 1(也就是 )。既然始终是 1,IEEE 754 为了极致榨干内存,直接规定这个 1 不存进内存。这样的话,内存里存的仅仅是小数点后面的部分(即上面公式中的 ),但是在计算的时侯,硬件需要自动把那个 1 加回来。 !ce6be79d-c521-45a1-b6d5-add7e59dbb69.png 那么对于FP32和FP16而言: - FP32:单精度,32bit,其中符号位1bit,指数位8bit,尾数位23bit,可表示的数据范围为 。 - FP16:半精度,16bit,其中符号位1bit,指数位5bit,位数为10bit,可表示的数据范围为 。 那么接下来,模型训练完成后保存的FP32的参数,要转换为FP16格式的话,具体的转换流程是什么呢?主要可以分为以下三个步骤: 第一步是指数位检查与溢出处理 (Overflow/Underflow)。 - 溢出 (Overflow) 检查:如上所述,FP16 能表示的最大绝对值是 65504。如果 FP32 的权重值大于 65504 ,转换器通常会执行 Clamp 操作,将超出部分强行截断为 65504。 - 下溢 (Underflow) 检查:FP16 能表示的最小的正规化数大约是 。如果 FP32 的参数值极小的话,转换器会将其强制为 0。 第二步是尾数位的强制截断。 FP32 有 23 位尾数,而 FP16 只有 10 位。转换器在进行转换的时候直接把后 13 个比特砍掉。在二进制里,这个截断操作相当于抹除了小数点后第 4 位到第 7 位的微小有效数字。当然,这一步也就是FP32到FP16转换中精度损失的主要来源。 最后一步是计算图的重构。也就是更换模型计算图中算子的执行逻辑,把其中FP32的算子(如Conv2D_Float32)操作替换为FP16的算子(如Conv2D_Float16)。 以上三个步骤的完整转换流程如下图所示: !FP32_to_FP16_Conversion_Flowchart_RK3588_%282%29.png 从以上的三个步骤的操作来看,从FP32的模型转换为FP16,模型的推理结果和精度等可能被影响的主要来源于两个方面的因素:指数位的溢出和尾数位的强制截断。但实际上,对于绝大多数 CV 模型和音频模型,FP32 转 FP16 的精度几乎是无损的,这是什么原因呢? 针对指数位溢出的问题,无论是 CNN 还是 Transformer,模型在经过初始化训练后,其权重参数 绝大多数都严格服从均值为 0、方差极小的正态分布。而且当前的 CV 和音频模型中普遍配置了 BatchNorm (BN) 或 LayerNorm (LN) 归一化层,这些归一化层在每次卷积或注意力机制计算完成后,会强制将特征图的数据分布重新拉回均值为 0、方差为 1 的标准状态。这样也就意味着,网络中 99.9% 的权重值都在 这个极小的区间内,FP16 的最大值 65504 ,指数位溢出的概率在权重端几乎为零。 而尾数强制截断所带来的精度损失问题,则通过尾数截断时所采用的阶段策略来缓解。在FP32向FP16转换的过程中,对尾数位的截断采用了一种向偶数舍入 (Round-to-Nearest-Even, RNE)的截断策略(这个策略有点类似于十进制的四舍五入)。如果使用简单的直接截断和舍弃,误差会永远偏向一方,这样经过成千上万次累加后,误差就会如滚雪球般变成灾难。但是,RNE 使得截断误差一个均值为 0 的对称随机噪声。这样的情况下,当模型对成千上万个带有零均值、独立噪声的乘积结果进行求和时,正向的误差和负向的误差在统计上会相互抵消,这样就可以极大程度上缓解强制截断的精度损失和误差问题。 INT8量化的计算过程 与 FP16 在 IEEE 754 标准的基础上做位宽截断的处理过程完全不同,INT8 量化是一场精密的数学空间映射。 它需要将 FP32 的连续的、动态范围极大的浮点数空间,塞进只有 256 个刻度()的离散整数空间中。 对于以上的这个映射,业界标准的做法是使用线性映射变换。这个映射变换由两个关键参数决定: - 缩放因子S:FP32 浮点数,代表了 INT8 空间里一个刻度单位对应于 FP32 空间里的真实范围大小。 - 零点偏移Z:INT8 整数,代表了 FP32 空间里的绝对零点,对应于 INT8 空间里的哪个整数刻度。 基于以上两个参数,假设 FP32 空间内的真值为 ,其对应的 INT8 空间内的量化值为 ,那么 和 之间转换的基本等式就是: 从真值 R 向量化值 Q 计算的公式就是: 其中: - 代表四舍五入到最近整数的操作。 - 则代表防溢出操作,把结果死死限制在 INT8 的合法范围内(也就是在 和 之间,如 )。 而从 FP32 到 INT8 的全流程计算过程也可以分解为以下三个步骤。其实 INT8 的量化计算就是执行以上的量化值的计算公式,只不过在执行这个公式之前首先要算出来其中的参数 和 。 首先是步骤一:要计算缩放因子 S ,在量化值 的范围确定的情况下(对于INT8而言就是-128到127共计256个刻度),首先要确定清楚 FP32 空间对应的真实值 的区间范围 和 。这样才能把 的范围准确的映射到 的范围之内。 这里针对参数权重/偏执值和激活值有两种情况: - 对于参数权重值和偏置值而言:因为这些值都是模型训练好后就确定下来的常量,所以在模型转换器(如瑞芯微的RKNN-Toolkit2)在INT8量化的执行过程中,只需要直接扫描 ONNX 文件里这一层卷积核的矩阵,就可以直接找出 和 。 - 而对于激活值而言:激活值是会随着输入图像的特征数据动态变化的,这就是为什么在进行 INT8 量化的时候,必须要基于训练图片集提供一组量化数据集 dataset(通常包含 20-50 张代表性图片)。INT8 量化的过程中,模型转换器会使用这些图片做一次前向推理,统计每一层输出特征图的概率直方图,然后再使用 KL 散度 (KL-Divergence) 等算法,找到一个最能保留信息量的最优截断阈值 和 。当然这样找到的 和 是由我们提供的量化数据集dataset中的数据计算出来的,所以最好我们提到dataset数据集中包含的图片与量化后实际使用的图片形态相差不大。 步骤二:有了步骤一计算出来的 和 ,接下来就可以计算出来参数 和 。计算这两个参数的流程有两种方法,非对称量化(针对激活值)和对称量化(针对权重值)。 针对权重参数的对称量化: 模型训练出来的权重值的分布(即 和 )通常以 0 为中心,左右基本对称。硬件为了计算极速,强制要求量化零点 ,INT8 量化值的目标范围为 。如 和 为,计算出来的 和 Z 就是: 针对激活值的非对称量化: 非对称量化可以充分的利用 INT8 量化的所有刻度,假设 ,计算 和 的流程就是: > 💡 为什么激活值使用非对称量化,权重值使用对称量化?这是因为,现代 CV 网络中大量使用 ReLU 系列激活函数。经过 ReLU 之后,特征图中的所有负数都被置为 0。此时如果强制对这种单边分布使用对称量化,即强制将映射范围的中心定在 。此时为了能表示 这样的数字,量化刻度就必须覆盖 并映射到 INT8 的 。这样的结果就是 INT8 中 这 127 个状态永远不会被用到(因为根本没有负数激活值),一半量化值被白白浪费掉了,8bit的量化实际上变成了7bit_。_但权重的分布天然就是以 0 为中心的(高斯分布),所以用对称量化基本不会浪费空间,还可以更高效的利用硬件计算加速。 步骤三:物理转换并固化。 第二步计算出来了 和 ,接下来模型转换器就会将所有的 FP32 权重,套用如下公式全部计算成 INT8 数值,并打包到量化模型文件中。 以上描述的INT8量化计算流程的整个流程图如下图所示。 !FP32_to_INT8_Quantization_Flowchart_RK3588.png
案例解析Gitops驱动AWS云原生应用的开发与部署流程
本文通过一个简单的Python项目演示在AWS中基于Gitops的理念进行代码开发、测试和生产环境的自动化部署的完整流程。 该案例的大致需求是: - 在本地客户端上通过HTTP发出请求(请求消息中包含了一个文件名字符串)给AWS API Gateway; - AWS Gateway收到以后转发给Lambda; - Lambda在S3中根据文件名创建一个文件并给客户端返回消息。 1.Gitops进行云原生应用的开发流程简介 在传统的运维模式中,我们习惯于使用命令式操作来进行云端环境的运维和管理工作(例如在AWS的web console页面中手动输入命令来创建 S3 桶,或手动打包代码上传到S3中等)。而在当前日益流行的 GitOps 的理念下,将基础设施即代码 (也就是所谓的IaC,Infrastructure as Code) 与 CI/CD 流水线深度结合的方式,可以让运维工作更加高效和可靠。 Gitops的核心思想非常简单:项目代码的 Git 仓库是系统状态的唯一真实来源,云端环境的部署以 Git 仓库中提交的代码为基础自动展开。 !image.png 这套标准化的开发与测试流程如下: 1. 编码与测试环境:开发人员在本地 IDE 中编写业务代码(Python、Java、Node.js等)和基础设施架构的定义文件(YAML),并在本地利用使用单元测试工具(例如Python的 pytest )跑通基础单元测试。 2. 代码提交 (Git Push):开发人员将代码推送到 GitHub 的 main 分支上。 3. Github 流水线与自动化测试:前一步的代码推送自动触发 GitHub Actions 流水线。Actions 收到代码提交后基于最新代码拉起隔离的容器环境,安装其中定义的 pipeline 的配置文件进行依赖安装与单元测试。如果这个自动化流程中执行的测试失败,流水线直接红灯阻断报错,防止错误代码污染云端。 4. AWS 云端自动编排 (SAM & CloudFormation):以上的测试流程通过后,Actions 继续基于严格的权限控制(OIDC),自动调用 AWS 的云端基础设施部署接口(Cloud formation),这个过程中会执行代码编译、打包,并将基础设施平滑部署到 AWS 环境。 通过这种的这种高度自动化的方式,可以彻底消除环境差异。开发人员只需专注写代码,剩下的工作全交给流水线来完成。 2.本地环境以及代码结构准备 以上的 Gitops 流程的实现,需要首先将项目从本地联调模式升级为生产环境部署模式。对应于以上流程的一个标准化的Python工程目录树应该如下所示: 其中的 template.yaml 文件是AWS CloudFormation的基础设施模板定义文件,可以认为是该项目向 AWS 提交的建筑施工图纸。具体内容在后续的AWS CloudFormation 的执行流程环节详细介绍。 其中的 .github/workflows/pipeline.yaml 文件中定义了Github Actions CI/CD 流程的自动化执行规则,在后续讲解Github的Actions执行流程中详细介绍。 src/app.py 是该Demo在AWS Lambda中执行的核心业务逻辑代码,最终这个代码会被部署到AWS的 Lambda 中。需要注意,在生产环境中,Lambda 必须包含完善的错误捕获、CORS 跨域支持以及结构化日志。 这部分的代码如下:主要的流程就是对API Gateway 发过来的请求消息进行解析,取出其中的filename字段,然后在S3中创建一个文件。 后续要在 Github Actions 定义的CI/CD流程中执行自动化测试,在此就需要提前写好单元测试的代码,该案例的单元测试的代码在 test/test_app.py 中: 代码提交后,在Github Actions的流水线在AWS的cloudformation中执行具体的部署之前, Actions 会先运行以上的这段测试代码。如果测试不通过(如断言失败),程序会抛出非零退出码,流水线会自动触发以阻断代码在生产环境中的发布。 3. AWS OpenIDC角色设置 OIDC (OpenID Connect) 是一种基于 OAuth 2.0 的身份认证协议。当Github的流水线运行时,GitHub 会给当前的 Runner 颁发一张带有数字签名的临时数字身份凭证 (JWT Token)。Runner 会基于这个凭证访问 AWS 。AWS 验证签名发现确实是 GitHub 颁发的,并且确认了来访者是指定的那个仓库的 main 分支,就会给 Runner 发放一组有效期极短(通常为 1 小时)的临时开门权限,用完即废。这就彻底消灭了需要手动管理的长期密钥,实现了真正的零信任和自动化安全。 要实现以上描述的这个机制,需要完成三步:在 AWS 里告诉它信任 GitHub、在 AWS 里创建一个专属角色、在 GitHub 流水线里设置为OpenIDC登录方式。 首先,在 AWS 中将 GitHub 注册为“受信任的身份提供商”。 登录 AWS 控制台,进入 IAM 服务,在左侧导航栏选择身份提供者 (Identity providers),然后点击 添加提供商 (Add provider),并选择 OpenID Connect,填写以下信息后点击添加提供者: - 提供商 URL (Provider URL): https://token.actions.githubusercontent.com - 受众 (Audience): sts.amazonaws.com 其次,在 AWS 中创建一个供 GitHub 扮演的 IAM 角色 (Role)。 在 IAM 左侧导航栏点击 角色 (Roles),然后点击 创建角色 (Create role)。按照下图进行填写和选择: !dbefdaa7-e601-4a2a-866e-fb460c90437e.png 接下来要对这个角色添加权限 (Add permissions):为了后续的CI/CD流程中让 SAM 能顺利部署资源,此处赋予 该角色AdministratorAccess权限。最后把该角色命名为 GitHubActionsDeployRole并创建角色即可。 以上的角色创建后,进入该角色的详细信息页面,记录下其ARN,后续需要配置在Github Actions所要求的pipeline.yaml文件中: !11e67041-bc7c-4255-b8ce-8a21a9d8492c.png 现在AWS中要进行的配置和修改就结束了,下一步需要在Github Actions的流水线配置文件中进行配置。 4. Github的Actions执行流程 那么Github的Actions究竟是如何启动并执行自动化的CI/CD流程的?答案是基于代码提交的.github/workflows/pipeline.yaml 文件。当开发人员在本地执行 git push 时,GitHub Webhook 会自动触发此文件来执行完整的 CI/CD 流水线。 Github Actions 背后的工作逻辑是:Github的后台引擎只会监听项目根目录下的 .github/workflows/ 这个文件夹中的yaml文件(只要后缀是 .yml 或 .yaml 即可),可以有多个流水线并行工作。该目录下的yaml配置的文件名可以自定义,所以在真实的商业项目中,通常会在 .github/workflows/ 目录下放多个文件,各司其职。例如: - unit-test.yaml:定义只要提交代码(无论什么分支),就会运行 Python 单元测试。 - deploy-prod.yaml:定义只有当代码推送到 main 主分支时,才执行部署到 AWS 云端的全套动作。 在对这个yaml配置文件的解析中,GitHub 会自动根据文件里 on: 关键字定义的条件,决定唤醒哪个流水线。 对于当前的这个demo项目而言,其对应的pipeline的yaml配置文件为: 4.1 Actions判断单元测试 问题:每次我们把代码推送到Github以后,Actions是如何判断要执行哪些单元测试文件的,以及如何判断单元测试执行成功的? 对应以上的第一个问题,Actions判断要执行的单元测试的内容由其pipeline的yaml文件来限定,对于这个demo就是上面的: 也就是,当前demo要做的单元测试就只有test下的test_app.py这个源文件。如果给 pytest 指定的不是单元测试文件,而是一个目录的话,pytest 会向下递归搜索该目录中所有的 Python 文件,但它只认文件名以 test_ 开头(如 上面的test_app.py)或以 _test.py 结尾的文件,并只运行其中名字以 test_ 开头的单元测试函数。 对于上面的第二个问题,Actions 判断单元测试是否成功的标准与单元测试文件中的assert语句相关。当assert语句中指定的条件成立的话,表示单元测试运行正常,继续往下执行,直到完整的单元测试流程执行完毕,并向系统返回退出码 0 表示整个过程顺利完成;如果有一个assert语句的条件不成立,程序会抛出AssertionError 异常,并返回退出码 1 。 GitHub Actions 中的操作系统对每个执行步骤的退出码进行检测,如果退出码为 0 表示该步骤顺利完成,否则会立刻判定当前步骤执行失败,并阻断后续所有命令的执行,返回错误。 5. AWS CloudFormation执行流程 在 CI/CD 流程中,基础设施即代码 (IaC) 的核心思想是:所有的云资源都应该由代码定义和自动创建,而不是人工去 AWS 控制台点选。而这部分工作就由 template.yaml 文件来进行定义。 在前面 Github Actions流水线配置文件.github/workflows/pipeline.yaml 中,最后一步执行的这个命令sam deploy --stack-name my-iot-edge-stack命令就负责基于template.yaml 文件把该文件中定义的AWS云端基础设施落实在云端的环境中。 - sam deploy 读取 template.yaml 配置文件,将该配置文件以及完整的部署包,通过 OIDC 获取的临时权限,发送给 AWS 底层的一个核心服务——AWS CloudFormation。 - CloudFormation 收到以上配置文件后,会自动计算出需要执行哪些底层 API 来按顺序创建 S3 Bucket、Lambda和 API Gateway。 - 这个自动部署的过程,如果有任何一步失败,CloudFormation 会自动回滚(把已经建了一半的资源全删掉),保证云端环境永远不会处于“半残废”的脏状态之下。 该demo对应的template.yaml如下所示: 问题:如果后续开源人员对当前的代码进行修改,每次修改以后提交到Github上,它都会执行自动部署的pipeline去创建S3 Bucket、Lambda Function以及API Gateway。那么如果之前的提交已经创建过了这些资源的话,会发生什么事情? 答案是:无论以上的流水线执行多少次,云端最终的状态都只会和云端环境部署代码里声明的状态保持一致。 在 Actions 流水线第一次运行 sam deploy --stack-name my-iot-edge-stack时,AWS CloudFormation 会在云端创建了一个名为my-iot-edge-stack的“逻辑档案袋”。 !0ab67a79-aa9d-4eb7-a70b-e6549873cf97.png 这个档案袋里记录了该流水线创建的的 S3 Bucket、Lambda、API Gateway 的所有当前状态和唯一 ID,而且AWS 牢牢记住了这些资源与该流水线之间的关联关系。 后续修改了代码并再次推送时,流水线会把新的图纸和代码打包发给 AWS,AWS 收到后不会立刻去覆盖,而是根据具体的情况分别进行处理: - 如果只修改了业务代码 (如app.py):也就是说template.yaml 的内容没有发生变化(即不需要动基础设施),只有 Lambda 的底层压缩包哈希值变了。此时,AWS 只会把新的代码包部署到现有的 Lambda 函数上,替换掉旧代码。之前的 S3 Bucket 和 API Gateway 完全不会被触碰,S3 里的历史文件也完好无损。 - 修改了基础设施参数 (template.yaml):例如把Lambda Container配置的 MemorySize: 128 改成了 MemorySize: 256。此时AWS 的判断是Lambda 的配置属性发生了变化。它会通过底层 API 直接修改现有 Lambda 函数的配置,将其内存扩容至 256MB。同样,S3 和 API 保持原样。 - 什么都没改,不小心又触发了流水线:即新代码和档案袋里的状态 100% 一致。那么 Github Actions 流水线会在 sam deploy 这一步直接输出 No changes to deploy. Stack my-iot-edge-stack is up to date,然后以绿色的成功状态秒级结束,不会做任何多余的操作。 以上流程中需要注意的是,S3 Bucket 是用来存核心业务数据的,CloudFormation 对存储类资源有特殊的保护逻辑。如果某次提交的 template.yaml 里把 IoTDataBucket 这一大段代码直接删除了(或者给它改了名字),然后推送到 GitHub。流水线去更新时,AWS 默认是不允许直接删除带有数据的 Bucket 的,这会导致部署直接报错 (Update Rollback),从而保护生产数据不被一次手滑的 Commit 删光。 6.测试验证 经过以上完整的准备工作以后,提交代码到Github的main分支上,其对应的Actions会自动启动,执行其中的单元测试,并且在单元测试通过以后自动在AWS上部署云端环境: !f7a8a8b2-6abb-43f9-b885-fa562efa483c.png 整个过程结束以后,就可以在 AWS Lambda中查看具体的部署情况及其对应的API: !dab16dbf-a3de-4640-917d-fd704f430e06.png 接下来就可以在terminal等终端上通过curl命令进行测试了(需替换成自己的API):
PSRAM和LPDDR是如何降低功耗的?
因为DRAM特有的自刷新特性与高频通信信号的处理,DDR始终是电子系统设计中功耗大户,本文重点总结LPDDR以及PSRAM在降低功耗方面所做的针对性设计对策。 !image.png DDR的功耗问题 随着频率的飙升,现代DDR(特别是DDR5)早已成了主板上的耗电大户。这也是为什么现在我们PC上的高端内存条都必须穿上厚重的金属散热马甲,甚至还要单独配置电源管理芯片(PMIC)。 !image.png 那么DDR的高功耗问题从何而来呢?大体上,DDR高功耗的原因可以归结为以下三大核心部分。 动态功耗 对于这个数字电路动态功耗的计算有一个非常经典的功耗计算公式: 总结起来就是:数字电路的动态功耗,与工作频率 ,电压 的平方以及寄生电容 成正比。 现在的DDR4动辄3200MT/s,DDR5更是飙到了5600MT/s甚至更高,也就是说其内部基频高达2.8GHz以上。在这样的高频率下,芯片内部数以亿计的晶体管和外围的几十根数据线、时钟线,每秒钟要进行几十亿次的电平翻转(从0到1/从1到0)。这种高频开关动作会产生巨大的瞬间电流,也是DDR在工作状态下最大的发热源。 同样,电路板上的PCB走线和接插件会带来了一定的的寄生电容(对应于上面动态功耗计算公式中的 ),以及为了保证信号在PCB走线并经过分叉后依然精准,DDR4必须要维持 (DDR5为 )的较高I/O驱动电压,按照以上的动态功耗计算公式,其功耗会被指数级放大。 静态模拟损耗 当频率进入微波级别(如以上提到的DDR5600的基频达到了),DDR必须在外围接口模块(也就是DDR的PHY模块)挂载非常耗电的高级模拟电路来保证高频通信信号不畸变: - DLL(延迟锁相环): 为了确保在纳秒级甚至皮秒级的窗口内精准对齐外部时钟和内部数据,DLL模块必须保持在后台高速运转,不断侦测并强行补偿微小的物理延迟。只要时钟不停,DLL的耗电就不会停,这是产生静态底电流的来源之一。 - ODT(片内终端电阻): 高频信号在长的PCB走线上会产生严重的电磁反射。为了吸收这些反射波,DDR会在接收数据时瞬间开启内部的ODT电阻。这就相当于在电路上铺设了一条直流通路,信号会直接化为热量消散,变成实打实的热损耗。 与DLL和ODT的相关工作原理,可以参考PSRAM能成为DDR缺货的解决方案吗? 一文。 DRAM的自刷新功耗 本质上,DDR的底层是DRAM存储阵列,每一个bit的数据都要靠微型电容里的电荷来维持。 而现实中的电容会不可避免地漏电。为了不让数据丢失,即使系统完全闲置(没有任何读写操作),SoC主控也必须每隔几毫秒就向DDR发送一次自刷新命令,强制对芯片内部把几亿个电容频繁充放电荷。 这种大规模充放电的工作机制,导致DDR即使在待机休眠时,也无法像静态逻辑电路那样做到真正的零功耗。 具体DRAM的工作原理,同样可以参考PSRAM能成为DDR缺货的解决方案吗?一文。 LPDDR是如何缓解功耗问题的? 针对以上DDR存在的高功耗问题,LPDDR在设计时,以低功耗设计优先的原则,对标准DDR的底层物理架构进行了针对性的革新设计,在继续维持高数据吞吐率的情况下,极大降低功耗,使之更适合笔记本、手机这类移动高性能计算设备。 !image.png 针对动态功耗 依然是数字电路动态功耗的计算公式: 。 要在保持高频率()的情况下降低功耗,首先在I/O接口电压()的角度做文章。 如上所述,标准 DDR4 的核心和 I/O 电压通常都是 1.2V。而 LPDDR4X 则把负责外部通信的 I/O 电压(VDDQ)直接降低到了 0.6V, 只有 的四分之一。这就意味着,单纯在数据总线的高低电平翻转上,LPDDR4X 就比 DDR4 节省了 75% 的动态功耗。 此外。为了在这么低的电压下保证信号不失真,LPDDR 采用了专用的低压摆幅终端逻辑(LVSTL),并要求主控与内存的物理距离必须极短(通常采用 PoP 叠层封装或紧凑的 SIP),这样也有助于降低PCB走线的寄生电容 。 针对静态功耗 如上所述,为了对齐高频通信中的时钟信号,DDR 增加了一个专门的 DLL 模块,这个模块即便是系统处于空载状态下也要持续运行,且极度耗电。 因此,LPDDR 在芯片设计中彻底抛弃了其内部的 DLL 模块。取而代之的是,针对时钟信号对齐问题,它要求主控 SoC 的内存控制器在系统开机时,执行极其复杂的Training(链路训练)算法,由 SoC 的 LPDDR 控制器去测算每根数据线的延迟,然后在 SoC 内部进行主动相位补偿。 这样就把信号同步的压力转移给SOC主控,LPDDR 也因此甩掉了最大的静态功耗包袱。 引入 TCSR 与 PASR 机制 对于其内部DRAM阵列所执行的自刷新动作,标准 DDR 不做任何区分,无论当前温度高低和数据有没有用到,对整个阵列中的所有 Bit 都按最高频率通刷,这样实际上就造成了极大的功耗浪费。 因此,LPDDR 内部集成了两个智能控制刷新的机制来优化功耗: - TCSR(温度补偿自刷新): 芯片内部有温度传感器,当感知到设备是冷机状态时(这种状态下电容漏电相对较慢),就会自动把自刷新频率降低。 - PASR(部分阵列自刷新): 针对休眠的情况,在主控休眠前,由操作系统通过专门的指令告诉 LPDDR 哪几个 Bank 是空的,这样在休眠的过程中,LPDDR 在自刷新时就可以直接对空 Bank 断电,只维持有数据的 Bank 自动刷新即可。 通过以上三个维度对于功耗的针对性优化设计,LPDDR 的功耗相比 DDR 有了大幅度的降低: !6cf5a78f-b0c9-4fac-a6d5-c712ac8c7627.png PSRAM的功耗问题解决之道 尽管如PSRAM能成为DDR缺货的解决方案吗? 一文所总结的,PSRAM 与 DDR/LPDDR 实际上是针对完全不同的领域和应用的产品,但 PSRAM 的低功耗表现确实比较突出,所以这里同样总结一下PSRAM 在降低功耗方面所做出的努力。 如果说 LPDDR 是通过极其昂贵的先进制程和极其复杂的精细化管理,在保证性能的前提下实现了相对低功耗,那么 PSRAM 解决功耗问题的逻辑,实际上就是“断舍离”——也就是用简单粗暴的物理阉割和架构降维的处理思路,来换取极端的省电(当然性能也完全与 DDR/LPDDR 不在一个层次)。 下图是华邦一款PSRAM的功耗状况: !31a6bf33-c8c4-4a5f-8c66-813b1113aabe.png 针对动态功耗 仍然是基于数字电路的动态功耗公式来进行分析:。 对于动态功耗的优化,LPDDR 的做法是尽可能降低电压(),但是这样也要求SOC主控与LPDDR之间的距离尽可能短,而 PSRAM 的做法则是把频率()和引脚电容()降到最低。 - 串行总线: DDR 动辄 60 到 100 根I/O引脚,在主板上的庞大走线网络会导致寄生电容()很大。而主流的 OSPI PSRAM 只有 8 根数据线,整体引脚不到 12 个。 - 低频频段: DDR 的物理时钟普遍在 1200MHz 以上的微波频段, PSRAM 主动避免解决微波通信带来的复杂性问题,将最高时钟卡死在 200MHz 以内。 其结果就是,因为引脚少、频率低,主控 SoC 和 PSRAM 在进行数据通信时,需要克服的物理电容和翻转次数成数量级减少。因此,即便 PSRAM 的 I/O 电压依然采用常规的 1.8V(没有像 LPDDR 那样降到 0.6V,这样就对PCB的布局走线要求不高),其总体动态功耗依然远远低于 DDR。 针对静态模拟功耗 因为时钟频率低于200MHz,不需要面对高频通信信号问题,不需要 DLL 来强行对齐纳秒级的相位,也不需要 ODT 去吸收高频信号的电磁反射,这样就可以去掉 DDR 中静态功耗很高的 DLL 和 ODT 模块。 在没有数据读写时,PSRAM 的接口端可以进入绝对静默,静态功耗可以直接降低到零。 针对休眠底电流 无论是 DDR 还是 LPDDR ,即使在系统进入休眠状态的情况下,主控 SOC 的 DDR 控制器仍然要保持工作,对 DDR/LPDDR(LPDDR只是可以关闭掉部分空闲Bank的刷新) 内部的存储阵列保持刷新。这样也就导致DDR/LPDDR即便在休眠状态下,其休眠低电流也居高不下。 针对以上 DDR 必须由 SoC 外部管理的痛点,PSRAM 使用完全不同的自刷新和休眠控制逻辑,彻底解决了休眠状态下的底电流问题。而这一点,也是PSRAM很适合用于一些极端关注休眠功耗的应用的原因所在。 PSRAM内置了自刷新模块。这样在设备进入休眠状态时,主控 SoC 可以直接切断外部时钟并彻底断电。PSRAM 内部极其省电的微型 RC 振荡器苏醒,并以很慢的节奏给电容阵列补电,以维持数据不丢。 经过以上针对性的功耗优化,DDR 与 PSRAM 之间在功耗上也就存在着巨大的量级差异: 在满载工作状态下 - 标准 DDR4: 动辄消耗 2瓦 到 3瓦 的功率,电流在 数以百计的毫安 (mA) 级别,芯片表面会明显发热。 - OSPI PSRAM: 以 200MHz 吞吐数据时,电流通常只有 20mA 到 35mA 左右。 在深度休眠状态下 - 标准 DDR4: 即使进入进入休眠状态,其底电流通常依然高达 10mA 到 20mA,这一点也是 AOV Camera功耗居高不下的主要原因。 - OSPI PSRAM: 待机电流直接断崖式下跌,通常在 20µA 到 50µA 之间。 !7721f3d0-8063-4c86-abb5-0616b342f437.png
PSRAM能成为DDR缺货的解决方案吗?
在当前DDR内存市场供应紧张,价格波动剧烈的情况下,部分IPC领域的SOC供应商开始推广内置PSRAM的Camera SOC平台,PSRAM相比我们常用的DDR有哪些差异,适用于什么应用,本文尝试解释清楚以上问题。 要弄清楚PSRAM究竟是什么,首先要搞明白SRAM与DDR(DRAM)的区别。 SRAM与DRAM SRAM可谓是存储界的高富帅,目前最常用的就是CPU内部的L1/L2 Cache。它存储1个Bit的数据需要整整6个晶体管(6T架构)。这6个晶体管交叉耦合形成一个逻辑闭环(触发器)。 这种存储结构下,对于bit信息的存取非常简单可靠: - 写数据时: 在外部施加一个大的电压,强行把触发器的状态设置到某一边。 - 读数据: 直接测量触发器两端的状态。这个读取动作不会破坏触发器原来的状态,而且速度极快(纳秒甚至皮秒级)。 其优点是,这个存储结构极度稳定,只要不断电,状态永远锁死,不需要刷新,且对这个内存bit的读取是非破坏性的,速度极快。 但缺点肯定就是占地面积太大,容量很难做大,成本极其高昂。 下图是SRAM一个存储bit的电路结构: !image.png 而DRAM最初的诞生和后续的持续演进发展,都是为了解决以上的大容量和低成本内存问题。 在DRAM单个bit存储单元的设计中,只用了1个晶体管+1个微型电容。对于这个存储结构的类比,可以认为是:晶体管是水龙头,电容是小水桶。水桶装满水代表1,空着代表0。 这种bit存储结构存在一个致命的物理缺陷:电容会漏电。 因此在几毫秒内,满水桶就会漏成半水桶,最终1就会变成0。因此,为了维持位状态的稳定性,必须周期性地把晶体管打开检查(判断是0还是1),如果是1的话就重新把水(电容里面的电荷)注满。这就是DRAM需要动态刷新(Refresh)的物理本质所在。 更糟糕的是,DRAM每个bit的读写过程非常复杂: - 写数据的时候:先打开晶体管(水龙头),往电容(水桶)里灌电荷(1),或者把电荷抽干(0)。 - DRAM读数据的过程是一个破坏性读取的复杂过程: 首先要探测水桶里有没有水(电荷),要检测就只能把晶体管打开,让水桶里的水流到外面的总线(Bitline)上。通过外部的灵敏放大器(Sense Amplifier)感受到微弱的水流,判定这个bit里面之前的状态是0还是1。而因为在读取的时候水流出来了,因此读取完之后,原来的的数据状态就被破坏了。所以,DDR在每一次读取操作的最后,都必须强制加上一个写回的动作,把刚才读到的1重新灌回到水桶里。 !image.png 以上就是SRAM和DRAM工作原理的简单总结。而后续要介绍的DDR、LPDDR、PSRAM都是基于DRAM的,其内部的bit存储阵列结构及其读写过程都是如上所述的DRAM的情况。 > 💡 注意, PSRAM不是SRAM,而是DRAM。它之所以带个“P(伪)”,正是因为它挂羊头卖狗肉。它的内部结构依然是会漏电的DRAM,只不过是在硅片内部集成了一个微型控制器来自动做刷新动作,对外部主控伪装成了不需要刷新的SRAM而已。 要理解PSRAM究竟是如何工作的,一个比较好的切入点是先理解最常用的DDR究竟是如何工作的,再来看它与DDR之间的差异是什么。 DDR的技术壁垒到底是什么? > 需要注意,DDR的不同规范版本内置其更早的SDR等的内部结构与工作流程非常复杂,但本文的目的主要是为了解释清楚DDR/LPDDR与PSRAM之间在工作流程和结构上的差异,因此不会对更细节的内容进行总结和解读,只写出与PSRAM之间有明显差异的地方。 我们在产品设计中,在用到外置DDR的时候,经常会面对DDR功耗大以及电路设计复杂的问题,也正因为如此,目前主要Camera SOC厂商的方案普遍内包了DDR来降低系统的设计和调试难度。DDR的这个复杂性主要原因其对于高达几十GB/s的高吞吐量的追求。 下图是一个典型的SOC DDR控制器与DDR芯片之间的连接图: !image.png 为了追求SOC与DDR之间极高的吞吐率,目前的主流DDR5已经做到了5600MT/s (Mega Transfers per second,兆次传输每秒)甚至更高。 DDR(双倍数据速率)在通信过程中的基本原理是:利用时钟信号的上升沿传一次数据,下降沿再传一次数据。所以,当一个 DDR5 的数据吞吐率达到 5600 MT/s 时,它的实际物理时钟(也就是 SOC 端通过 CLK 引脚发送给 DDR 的那个真实的方波震荡频率)达到了 5600 / 2 = 2800 MHz (2.8 GHz)! 2.8 GHz 的基频,在 PCB 板上已经属于典型的微波频段。在这个频率下,主板上的铜箔走线已经不再是导线,而是变成了一根根微带天线,由这个天线所带来的信号反射、串扰、衰减等问题会非常严重,这才是高频DDR要解决的最核心的问题。解决这个问题所需要的高速模拟与混合信号设计能力,才是真正把中低端存储厂商和国际巨头(如三星、SK海力士、美光)隔开的分水岭。 为了解决以上的高频信号问题,高频DDR在信号设计中采用了DDL锁相环和ODT片内终端电阻的方案。 !0029a77a-d62b-4ee1-9a87-887fd73841b0.png DLL(Delay-Locked Loop,延迟锁相环)模块的作用主要是对抗DDR芯片内部的时钟延迟。 在外部SoC对DDR中的数据进行存取的通信过程中,其时钟信号经过PCB电路板的走线到达DDR引脚后,必须经过DDR内部复杂的布线树才能到达最终输出数据的寄存器,这段物理路径会产生约 0.1到0.2纳秒的内部传播延迟。 在没有DDL的情况下,等到DDR的数据到达SOC的引脚时,可能已经晚了半个甚至一个时钟周期。而外部SoC期望在时钟边缘准时收到数据,这样的存取结果读取到的就全是乱码。 而DLL模块的作用就像是一个极其精准的时序预判器。在工作过程中,它会不断测量外部时钟到达和内部数据吐出之间的那段固有物理延迟。然后通过内部的压控延迟线,故意把DDR内部用于触发数据的时钟提前,确保DDR返回的数据按照SOC的时钟准确的出现在其引脚上。 而ODT(On-Die Termination,片内终端电阻)的目的则主要是消灭信号回声。 如上所述,当传输线的信号频率达到GHz级别时,PCB上的铜线就不再是简单的导线了,而是传输线(Transmission Line)。当SoC全速向DDR发送数据(电磁波)时,如果信号冲到了DDR的引脚末端,发现阻抗不匹配,电磁波就会原路反弹回去产生回波信号。回波信号又会和 SoC 正在发送的下一个新波相撞,导致整个总线上的波形劣化(专业术语叫振铃、过冲、下冲),数据会瞬间全错。 为了应对以上射频信号的阻抗不匹配导致的回波问题,JEDEC规范决定:在DDR芯片内部(On-Die)的硅片上增加用来吸收反射波的终端电阻,这就是ODT。 PSRAM的结构与内部特性 相比于高速DDR在高频信号通信方面所面对的复杂性,PSRAM的结构就要简单很多。 绝大多数PSRAM的外部通信频率通常被限制在200MHz以内,这样就可以避开严重的电磁反射和纳秒级时钟偏移的问题,因此它的物理接口变成了常规的CMOS/LVCMOS收发器。 目前的主流PSRAM与主控SOC之间采用QSPI(四根数据线)和OSPI(八根数据线)的通信接口。SoC只需要发过来简单的SPI串行指令,PSRAM 会在其芯片内部把这些简单的指令,翻译成底层DRAM阵列需要的复杂指令组合(比如拆分成 Active激活行 -> Read/Write读写列 -> Precharge预充电)。所以SOC就不再需要内置复杂的DDR控制器。 !d4462f95-87b1-468b-a598-eef64d55edb3.png 相比DDR,PSRAM有一个重大的革新就是其内置了自刷新计数器,PSRAM在其内部通过这个自刷新计数器来完整接管其内部DRAM阵列的自刷新行为。在这种情况下,需要休眠的时候,主控SOC甚至可以真正关机(只要维持住PSRAM本身的电源即可),而不会影响PSRAM里面的数据,这样在休眠模式下其功耗就得到了极大程度的降低。 - 相比DDR,即使主机要休眠,SoC 的内存控制器不能断电,还要继续维持时钟引脚或者 CKE(时钟使能)引脚的特定电平状态。这就导致 SoC 内部始终有一部分电源域无法关闭,整机的底电流很难压下去。 所以,从总体上讲,PSRAM的设计哲学是牺牲极限的吞吐量和容量(因为通信的吞吐率太低,高容量就没有意义了,所以目前PSRAM的主流容量通常在 32Mb 到 256Mb之间),在芯片内部增加大量的逻辑电路解决掉DRAM阵列漏电的问题,给主控SoC呈现出来一个极度友好的接口,最终换取到的是极致的省电和极简的硬件设计。 总结 总的来讲,尽管DRAM内部的存储核心阵列(DRAM Cell)的制造仍然需要极高的工艺制程,但这并非是不可逾越的。DDR领域真正的技术壁垒,正是高速模拟与混合信号设计能力(也就是包含以上所简述的DLL、ODT、高速PHY接口在内的外围电路)。 对于很多做PSRAM或老旧规格DDR(如DDR2/低速DDR3)的厂商而言,他们的强项在于数字逻辑设计和低功耗控制。在100MHz到200MHz的频段里,数字信号还是比较理想的方波,因此不需要太复杂的模拟电路去修补信号。 但一旦想往高速DDR4甚至DDR5发展,厂商就必须组建顶级的模拟电路设计团队。他们要解决的不再是简单的0和1的逻辑问题,而是微波级别的电磁场问题。除了以上提到的DLL和ODT,现代高速DDR内部还必须集成 VREF(内部基准电压校准) 甚至 DFE(判决反馈均衡器) 等原本只在高端通信芯片(如PCIe、以太网PHY)里才会见到的高级模拟抗干扰技术。 这就是为什么市场上能做PSRAM的厂家多如牛毛,但能稳定供应高速LPDDR4X、DDR5的厂商屈指可数。因为后者的本质,是一个披着存储外衣的超高速射频/模拟芯片。 所以,结合以上DDR和PSRAM的内部架构组成和工作逻辑,就能清楚地看到,这两者根本面对的就不是同一个应用领域,根本就不具备可比性。 - DDR系列(包括常用于移动端的LPDDR)的核心使命是提供极致的内存带宽。只要系统跑的是庞大的操作系统(如标准Linux、Android、Windows),或者需要处理密集的矩阵运算和高清多媒体流,就必须由DDR来进行处理。 - 而PSRAM的目的则是在有限的PCB空间和极低的待机功耗下,为主控提供比片内SRAM大得多的缓存。只要设备是纯电池供电(低功耗),音频处理设备、低分辨率智能门铃、轻量级带屏IoT设备,使用PSRAM就非常合适,当然前提是软件架构从重型Linux转向RTOS,或者大幅优化应用层的内存占用和总线开销。 参考资料 - DDR中的ODT功能详解及波形对比_内存rdodt-CSDN博客