0%

在做 FPGA 设计时,需要不同频率的时钟,通常会使用 Xilinx 提供 MMCM/PLL 时钟 IP 分频或者倍频得到。偶数分频很简单,只需要用一个以 分频数/2 为最大值的计数器控制输出时钟翻转即可。但奇数分频不能用这种方法来实现,以 3 分频为例,其每个周期的高电平时间占原始时钟的 1.5 个周期,计数器无法计数 0.5 个时钟周期。

wavedrom
阅读全文 »

数字滤波器是从原始信号中提取用户所需要的信息,滤除不需要的信号成分。根据信号与干扰的不同关系,可以从时域、频域或变换域(同态)进行信号滤波设计。

数控振荡器

数控振荡器(NCO,numerically controlled oscillator)是软件无线电、直接数据频率合成器(DDS,Direct digital synthesizer)、快速傅立叶变换(FFT,Fast Fourier Transform)等的重要组成部分,同时也是决定其性能的主要因素之一,用于产生可控的正弦波或余弦波。

数控振荡器有多种实现方法,最常用的方式就是基于直接数字频率合成技术(DDS,Direct digital synthesizer)的三角函数发生器。与传统的频率合成器相比,DDS 具有成本低、功耗低、分辨率高和转换时间短等优点。

阅读全文 »

分频器是伴随着频率综合器的出现而发展起来的,在射频无线收发芯片中需要频率综合器输出高质量的本地载波来完成信号的上变频或下变频;在数字芯片中需要频率综合器输出各种不同频率的时钟来驱动时序电路完成各种逻辑运算。频率综合器中都需要分频器来讲高频时钟分频至低频时钟的任务。

阅读全文 »

锁相环(PLL: Phase-locked loop)是一种利用反馈(Feedback)控制原理实现的频率及相位的同步技术,其作用是将电路输出的时钟与其外部的参考时钟保持同步。当参考时钟的频率或相位发生改变时,锁相回路会检测到这种变化,并且通过其内部的反馈系统来调节输出频率,直到两者重新同步,这种同步又称为“锁相”(Phase-locked)。

阅读全文 »

在用 FPGA 进行图像处理时,通常的作法是接一个显示器,查看输出结果,不过这也太不方便了,手上的这块 PYNQ-Z2 带有千兆以太网口,就想着用以太网传输视频,这样就可以抛弃笨重的显示器了。由于 Lei 同学已经完成了裸机的方案(见千兆以太网视频传输),并且之前已经在 ZYNQ 上移植了 Linux 系统,那就做一个运行在 Linux 系统上的以太网图像传输吧。其实这样做起来更简单,网上可以参考的也一大堆。

GitHub Repository : https://github.com/Starrynightzyq/streaming-udp-video

这个工程是用 C++ 写的,UDP 传输,依赖 OpenCV2,在 Mac 与 Linux 以及 ZYNQ 上都测试通过了。

由于是为了验证图像算法的正确性,需要对输出的图像进行一些分析,因此我想得到的是原始的图像数据而不是压缩后的数据,稍微计算了一下,$ 640 24bit $ 大小,30fps 的帧率的视频码率是 27.648MBps,用千兆网传输足够了。

TODO

由于之前没有系统地学习过计算机网络的知识,这次补了一下。

UDP or TCP

TCP/IP 协议族映射到 OSI 模型中分为 4 层,从下往上分别是:网络访问(链接)层(Network Access(link) layer)、网络互连层(internet layer)、传输层(transport layer)、应用层(application layer)。TCP 和 UDP 工作在传输层。

TCP

TCP(Transmission Control Protocol) 是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP协议的运行可划分为三个阶段:连接创建(connection establishment)、数据传送(data transfer)和连接终止(connection termination)。

连接创建

TCP用三次握手(或称三路握手,three-way handshake)过程创建一个连接:

  1. 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三次握手的一部分。客户端把这段连接的序号设定为随机数A
  2. 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK的确认码应为A+1,SYN/ACK包本身又有一个随机产生的序号B
  3. 最后,客户端再发送一个ACK。此时包的序号被设定为A+1,而ACK的确认码则为B+1。当服务端收到这个ACK的时候,就完成了三次握手,并进入了连接创建状态。

如果服务器端接到了客户端发的SYN后回了SYN-ACK后客户端掉线了,服务器端没有收到客户端回来的ACK,那么,这个连接处于一个中间状态,既没成功,也没失败。于是,服务器端如果在一定时间内没有收到的TCP会重发SYN-ACK。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s才知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才会断开这个连接。使用三个TCP参数来调整行为:tcp_synack_retries 减少重试次数;tcp_max_syn_backlog,增大SYN连接数;tcp_abort_on_overflow决定超出能力时的行为。 three-way handshake

数据传输

在TCP的数据传送状态,很多重要的机制保证了TCP的可靠性和强壮性。它们包括:使用序号,对收到的TCP报文段进行排序以及检测重复的数据;使用校验和检测报文段的错误,即无错传输;使用确认和计时器来检测和纠正丢包或延时;流控制(Flow control);拥塞控制(Congestion control);丢失包的重传。

连接终止

连接终止使用了四路握手过程(或称四次握手,four-way handshake),在这个过程中连接的每一侧都独立地被终止。当一个端点要停止它这一侧的连接,就向对侧发送FIN,对侧回复ACK表示确认。因此,拆掉一侧的连接过程需要一对FIN和ACK,分别由两侧端点发出。

four-way handshake

TCP 包头结构

tcp-head

源端口 16位;目标端口 16位;序列号 32位;回应序号 32位;TCP头长度 4位;reserved 3位;控制代码 9位;窗口大小 16位;偏移量 16位;校验和 16位;选项 32位(可选);

这样我们得出了TCP包头的最小长度,为20字节。

UDP

UDP 是一个简单的面向数据报的通信协议。UDP 只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份(所以 UDP 有时候也被认为是不可靠的数据报协议)。UDP 在 IP 数据报的头部仅仅加入了复用和数据校验字段。

UDP 适用于不需要或在程序中执行错误检查和纠正的应用,它避免了协议栈中此类处理的开销。对时间有较高要求的应用程序通常使用 UDP,因为丢弃数据包比等待或重传导致延迟更可取。

UDP 的分组结构

udp-head

UDP 头部包含了以下几个数据:

  • 两个十六位的端口号,分别为源端口(可选字段)和目标端口;
  • 整个数据报文的长度;
  • 整个数据报文的检验和(IPv4 可选 字段),该字段用于发现头部信息和数据中的错误;

因此 UDP 的头部开销小,只有 8 字节,相比 TCP 的至少 20 字节要少得多,在传输数据报文时是很高效的。

UDP数据分包大小的原则与一些思考

编写程序时不可避免遇到一个疑惑,一次发多大的数据包为宜?理论上IP数据报最大长度是65535字节,这是由IP首部16比特总长度字段所限制,去除20字节的IP首部和8个字节的UDP首部,UDP数据报中用户数据的最长长度为65507字节,但是,大多数实现所提供的长度比这个最大值小。

以太网 IP 层的最大传输单元 (Maximum Transmission Unit,MTU) 为 1500 字节。如果以分包大小应该使在 IP 层不再进行分包为宜作为原则,那么因为 UDP 数据报的首部 8 字节,IP 首部 20 字节,所以 UDP 数据报的数据区最大长度为 1472 字节。如果说 IP 数据报大于 1500 字节,大于 MTU,这个时候发送方 IP 层就需要分片,把数据报分成若干片,使每一片都小于 MTU,而接收方 IP 层则需要进行数据报的重组,这样就会多做许多事情。而更严重的是,由于 UDP 的特性,当某一片数据传送中丢失时,接收方便无法重组数据报,将导致丢弃整个 UDP 数据报。因此,在普通的局域网环境下,建议将 UDP 的数据控制在 1472 字节以下为好,以降低丢包率。 进行 Internet 编程时则不同,因为 Internet 上的路由器可能会将 MTU 设为不同的值,鉴于 Internet 上的标准 MTU 值为 576 字节,建议在进行 Internet 的 UDP 编程时,最好将 UDP 的数据长度控件在 548 字节 (576-8-20) 以内。

TCP与UDP区别总结:

  1. TCP 面向连接(如打电话要先拨号建立连接);UDP 是无连接的,即发送数据之前不需要建立连接;
  2. TCP 提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付;
  3. TCP 面向字节流,实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的;UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等);
  4. 每一条 TCP 连接只能是点到点的;UDP 支持一对一,一对多,多对一和多对多的交互通信;
  5. TCP 首部开销 20 字节;UDP 的首部开销小,只有 8 个字节;
  6. TCP 的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道;

Reference

  • https://en.wikipedia.org/wiki/Internet_protocol_suite
  • https://en.wikipedia.org/wiki/Transmission_Control_Protocol
  • https://en.wikipedia.org/wiki/User_Datagram_Protocol
  • https://blog.fundebug.com/2019/03/22/differences-of-tcp-and-udp/
  • https://www.cnblogs.com/skyfsm/p/6287787.html

部署到服务器

Ref:

Hexo博客进阶:将Hexo部署到云服务器

将Hexo部署到自己的服务器上

no-www和www跳转

Ref:

nginx实现no-www和www跳转

强制 HTTPs 跳转

首先查看 Nginx 是否有 SSL 支持模块

使用命令:

1
nginx -V

看输出中是否有:

1
2
3
4
configure arguments:
...
--with-http_ssl_module
...

如果没有,则需要重新编译 nginx,增加 SSL 支持模块,参考为nginx添加SSL支持模块

安装 Nginx

参考:北海骆驼-Nginx的编译安装并支持ssl

申请&下载证书(略)

上传证书

在 Nginx 的安装目录 /etc/nginx/ 下创建 cert 目录,并将证书文件(SSL Key 和 CSR 文件)上传到 cert 目录中。

可以用 whereis nginx 查看 Nginx 安装目录

配置 Nginx

修改默认配置文件 /etc/nginx/sites-available/default :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
server {

# SSL configuration
#
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
#

# 定义服务器的默认网站根目录位置
root /var/www/hexo;

# ssl
ssl on;
ssl_certificate cert/1_example.com_bundle.crt;
ssl_certificate_key cert/2_example.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

server_name example.com;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}

}

# 重定向,强制 https & no-www 访问
server {
listen *:80;
listen *:443 ssl;
listen [::]:80;
listen [::]:443 ssl;
server_name www.example.com;
return 301 https://example.com$request_uri;
}

server {
listen *:80;
listen [::]:80;
server_name example.com;
return 301 https://example.com$request_uri;
}

修改配置后,使用如下命令,检查配置是否正确:

1
nginx -t

最后重启 Nginx。

阅读全文 »

最近用 Altium Designer 20 画了几个板子,经常卡死,真的让人崩溃,在排除电脑硬件问题及系统问题后,找到了 AD 软件自身的问题。

目前网上主要有两种解决方案如下:

1. 禁止 AD 自动联网

第一步:关闭 AD 自动更新

点击右上角的设置小齿轮,然后在 System-> Account Management 中改为 "No,…”,如下图:

ad1

在 System -> Installation 的 "Check frequency” 改为 “Never”,如下图:

ad2

第二步:设置防火墙,禁止 AD 联网

这步就是设置防火墙禁止 AD 软件联网,方法比较简单,参考:禁止Altium designer(其他软件同样适用)联网的配置操作

2. 删除多余的库

这个方法的思路在于 AD 有时候库过多导致打开的时间过长,个人觉得用处不大。参考:Altium教程:AD中pcb文件和库文件libraries卡死解决办法

Framebuffer 是用一个视频输出设备从包含完整的帧数据的一个内存缓冲区中来驱动一个视频显示设备。简单的来说,就是使用一个内存区来存储显示内容,改变内存的数据就可以改变显示的内容。 在 github 上有一个开源工程:framebuffer 完整的实现了 framebuffer驱动

阅读全文 »