一、握手协议基础

什么是握手协议

握手协议,说白了就是两个模块之间的一种「沟通约定」。

我刚开始做接口设计时,总觉得握手协议是个高大上的概念。后来发现,它其实就是一套规则——告诉发送方和接收方:什么时候可以发数据,什么时候该停下来等一等。

举个生活中的例子。你给同事递文件,你会怎么做?

  • 你伸出手,把文件递过去(发送方发出数据)
  • 同事看到了,伸手接住(接收方确认收到)
  • 你看到同事接住了,才松开手(发送方知道传输完成)

这个过程,就是一次握手。硬件里的握手协议,本质也是这套逻辑。

核心定义:握手协议是通信双方通过特定的信号线,协调数据传输开始与结束的一种控制机制。它的存在,是为了解决「发送方不知道接收方是否准备好」这个根本问题。

同步握手与异步握手

这里有个关键区分——同步和异步。我见过不少工程师在这上面栽跟头。

同步握手,依赖同一个时钟。发送方和接收方都在同一个时钟沿上采样握手信号。优点是简单、可靠,缺点是两个模块必须共用一个时钟域。

异步握手,不依赖同一个时钟。两个模块各跑各的时钟,通过握手信号来协调。我做过一个项目,CPU和外围设备之间就是异步握手——CPU跑200MHz,外设跑10MHz,没有握手协议根本没法通信。

特性 同步握手 异步握手
时钟要求 同一时钟域 可跨时钟域
实现复杂度 低 高(需同步器)
吞吐量 高 较低
典型应用 片内总线 片间通信

我的经验:能同步就别异步。同步握手出问题,查起来相对容易。异步握手一旦出bug,时序问题能让你调试到怀疑人生。

电平触发与边沿触发

握手信号怎么传递「确认」信息?两种方式:电平触发和边沿触发。

电平触发,靠信号的电平高低来表示状态。高电平表示「准备好了」,低电平表示「还没好」。这种方式简单直观,但有个问题——如果信号一直保持高电平,接收方怎么知道是「新的一次握手」还是「上一次还没结束」?

边沿触发,靠信号的跳变沿来表示事件。上升沿表示「开始握手」,下降沿表示「结束握手」。这种方式更精确,但需要检测边沿,电路稍微复杂一点。

我记得有一次,一个同事用电平触发做跨时钟域握手,结果接收方连续采样到高电平,误以为收到了多次数据。后来改成边沿触发,问题就解决了。

避坑指南:跨时钟域时,电平触发容易产生毛刺和误判。我建议在跨时钟域场景下优先使用边沿触发,或者加两级同步器做防抖处理。

握手的本质是「确认」

说了这么多,其实握手的本质就两个字——确认。

你想想看,为什么需要握手?因为发送方不知道接收方是否收到了数据。接收方也不知道发送方是否知道自己收到了。双方都需要一个「确认」的信号,才能保证数据传输的可靠性。

这个「确认」可以是显式的——比如专门拉一根ACK信号线。也可以是隐式的——比如通过数据总线的回读来确认。但不管哪种方式,核心逻辑都一样:我发给你了,你告诉我你收到了,我再发下一个。

我做过一个高速数据采集系统,ADC和FPGA之间就是靠握手协议来同步。ADC每转换完一个数据,就拉高一个「数据就绪」信号。FPGA读到这个信号后,把数据读走,然后拉低「数据就绪」作为回应。ADC看到信号变低,才开始下一次转换。你看,这就是一个完整的「确认」闭环。

一句话总结:没有确认的传输,就是不可靠的传输。握手协议,就是给数据传输加了一把「确认锁」。

知识体系总览

下面这张图,把本章的核心逻辑串起来了。我建议你多看几遍,理解每个概念之间的关联。

握手协议基础 什么是握手协议 通信双方的「沟通约定」 解决「是否准备好」的问题 同步 vs 异步握手 同一时钟域 跨时钟域 简单可靠 需同步器 电平 vs 边沿触发 电平触发 边沿触发 易产生毛刺 精确可靠 握手的本质:「确认」 没有确认的传输,就是不可靠的传输

一点建议:学握手协议,别死记硬背。你就想那个递文件的例子——什么时候伸手,什么时候接,什么时候松手。想通了,握手协议就懂了。

可可精品资料库