通过TCP从客户端传输视频流到服务端,并在服务端对数据进行处理后通过HDMI显示和传回客户端

 

目录

一、引言

二、使用TCP完成服务端和客户端的通信

三、 TCP解析视频数据,AXI_DMA读出数据并传输到HDMI显示

四、用于算法处理的图像数据源读出和ACP_DMA的写入


一、引言

本设计要实现:通过上位机软件将视频数据通过千兆网口(Ethernet)发送到ARM端;然后通过DMA(直接寄存器访问)的方式将视频数据读取出来;在PL端进行相应的算法处理;处理后的视频数据使用ACP接口写入内存中,可以保证缓存和DDR的一致性;再通过DMA将处理后的视频读出并通过HDMI显示,并且传回到上位机,设计思路如图1-1所示。

图1-1 设计思路

在本设计中:

HDMI接口显示黑白图像时使用8位数据,而数据流中的像素数据为16位,接口显示数据如何截取,可在配置包中进行配置。

配置寄存器数量为256个,前128个ps端用,后128个PL端用。

需要传输的3中数据包:

  • 前8个字节为0X33的代表配置包;
  • 前8个字节为0XCC代表图像数据帧头包,后面包含一帧的图像数据。在接收到该包数据后,进入当前帧图像数据接收模式,后续的数据不包含包头信息,只有图像数据。故在SDK中书写c代码时要注意第一个包中没有图像数据,合理使用读数据的条件避开。
  • ARM端接收到一帧图像数据后,要发送8个0XBB向上位机请求新的一帧图像数据。

配置包内容约定:

  • 配置包格式:8个字节包头(0X33) +  1字节寄存器地址 + 1字节读写方向设置(0写1读) + 4字节寄存器配置数据(高字节在前)。
  • 写寄存器配置包由上位机发起,开发板接收后进行解析并对相应寄存器进行配置,然后回读该寄存器当前值,对寄存器配置数据字段(4 字节)进行填充后然后进行反馈。
  • 读寄存器配置包由上位机发起,寄存器配置数据段填 0,开发板接收后进行解析并回读该寄存器当前值,对寄存器配置数据字段(4 字节) 进行填充后然后进行反馈。
  • 地址 0 HDMI 显示模式配置寄存器,该寄存器可配置数据为 08,0表示HDMI接口显示数据为16位原数据的最低八位,8表示最高8位。
图1-2 HDMI显示数据选择
  • 地址 1 为图像水平尺寸配置寄存器,该寄存器可配置数据为 11280, 用于指定图像列数。
  • 地址 2为图像竖直尺寸配置寄存器,该寄存器可配置数据为 11024, 用于指定图像行数。
  • 地址 3 为图像读回到上位机标志,1 为读回,0 为不读回。
  • 其余地址段预留。

二、使用TCP完成服务端和客户端的通信

LwIP是Light Weight(轻型)IP协议,有无操作系统都可运行,其实现的重点是在保持TCP协议主要功能的基础上减少对RAM的使用。在本设计中,选用LWIP的Socket API模式。

1.实现方法:

  (1)在vivado软件中创建block design,添加zynq,在zynq里面打开Ethernet的I/O口;

  (2)然后在SDK中以“FreeRTOS lwIP TCP Perf Server”为模板建立新的工程,在里面更改相应的IP、掩码MASK、网关和服务端端口;

  (3)板卡下载bit文件,并且启动ARM调试,使用网线连接计算机和板卡,使用cmd命令符验证板卡和电脑是否互通;

  (4)验证互通后,在zynq中打开GP0口;创建自定义IP使用AXI-LITE接口来实现寄存器列表conf_list。SLAVE、LITE。寄存器的值将来会被其他模块使用,使用将值引出到端口。寄存器基地址在 “Address Editor” 里面查看。

output reg [3:0]		hdmi_bit_sel,
output reg [11:0]		img_width,
output reg [11:0]		img_high,



always @(posedge S_AXI_ACLK) begin
	  if(S_AXI_ARESETN == 1'b0) begin
	      hdmi_bit_sel <=0;
	      img_width <= 0;
	      img_high <= 0;
	  end
	  else begin
	      hdmi_bit_sel <= slv_reg0[3:0];
	      img_width <= slv_reg1[11:0];
	      img_high <= slv_reg2[11:0];
	  end
	end

  (5)在SDK 中根据以下项目要求书写收包程序,主体部分如图2-1;由于此时项目还未完全完成,所以暂时使用matlab来开发TCP客户端的发包程序。在matlab中查看“recv_data”,看是否正常通信,如图2-2所示。

图2-1 SDK中发包程序主体
%matlab代码

clc;
clear all;
close all;
warning off;
%tcp object create
tcp = tcpip('192.168.1.10',10000);
%set rx tx buffer
set(tcp,'InputBufferSize',256*64);
set(tcp,'OutputBufferSize',256*64);
fopen(tcp);
psplconfig=[8,640,512,0];%hdmi sel width high readback
conf_list=zeros(1,14,'uint8');
recv_data=zeros(length(psplconfig),14,'uint8');
for p=1:length(psplconfig)
 for i=1:14
 if i<=8 
 conf_list(i) = 85;
 elseif i == 9 
 conf_list(i) = p-1;%reg addr;
 elseif i == 10
 conf_list(i) = 0;
 elseif i == 11
 conf_list(i) = uint8(bitand(bitshift( psplconfig(p),-24),255));
 elseif i == 12
 conf_list(i) = uint8(bitand(bitshift( psplconfig(p),-16),255));
 elseif i == 13
 conf_list(i) = uint8(bitand(bitshift( psplconfig(p),-8),255));
 elseif i == 14
 conf_list(i) = uint8(bitand(bitshift( psplconfig(p),0),255));
 end
 end
 fwrite(tcp,conf_list);
 pause(0.0001);
 recv_data(p,1:end)= fread(tcp,14,'uint8')';%转置
end

图 2-2 matlab中recv_data的返回值

三、 TCP解析视频数据,AXI_DMA读出数据并传输到HDMI显示

 1. 上位机下发的TCP包解析出数据后,在此阶段暂时存储在DDR的0X3000000中,因为此阶段还不实现算法的处理。在此阶段,上位机下发的TCP包经解析后,配置相应的寄存器列表并将配置数据传输到此阶段的AXI_DMA模块中;解析后的视频数据便放在了ps端的cache中,为了将视频数据同步到DDR中,在SDK中注意实现此功能。这里我们不采用关闭cache的方法,因为关闭cache后,TCP的效率非常低。

Xil_DCacheFlushRange(recv_buf,read_bytes);

2.实现方法:

(1)在zynq中打开HP0口。

(2)AXI_DMA实现数据读取。创建自定义IP,实现HP0口读取DDR 的数据,这里仍然是在原来的模板上自己修改,依然采用两帧缓存,防止图像撕裂。这些在项目“IMX222摄像头显示”里有介绍,这里不再赘述。起始地址设置0X3000000.

(3)HDMI显示模块在“IMX222摄像头显示”里也有介绍。

(4)SDK程序的设计,在第二部分程序的基础上,我们需要增加图像数据包的收包程序,要求为:“前8个字节为0XCC代表图像数据帧头包,后面包含一帧的图像数据。在接收到该包数据后,进入当前帧图像数据接收模式,后续的数据不包含包头信息,只有图像数据。故在SDK中书写c代码时要注意第一个包中没有图像数据,合理使用读数据的条件避开;”

(5)接下来便可使用matlab来进行测试,需要在上一步matlab的基础上加上发送图像数据包的内容。

四、用于算法处理的图像数据源读出和ACP_DMA的写入

1.这里仍然采用DMA 的方式从HP2口读取ddr,在这个阶段,TCP解析出来的图像数据就放到0X2000000中,经算法处理后的图像数据再放到0X3000000中,再通过DMA方式从HP0口读取ddr 0x3000000并通过HDMI显示。

2.使用ACP接口是解决了一致性问题,也就不需要关闭cache,避免降低TCP的效率。

3.HP0和HP1共用一个DDR控制器接口,HP2和HP3共用一个DDR控制器接口,虽然都有均衡器处理,但是我们在端口空余的情况下,还是独立使用,故本设计中使用了HP0和HP2.

4.实现方法:

(1)在zynq中打开HP2口和ACP口;

(2)创建自定义IP,AXI_RD_DMA模块,也需要自己修改;

起始地址设置0x2000000;

注意写入数据高低字节相互对调;

fifo里面数据量的判断启动DMA读的条件。

(3)创建自定义IP,WR_ACP模块,该模块也需要自己修改,

起始地址设置0x3000000;

这里注意:为使数据不丢失,一致性的写入DDR中,要将“M_AXI_AWCACHE”设置为4‘b0011;

同时也要输出出帧标志,给“三”中的AXI_DMA模块,用于判断当前写的区域,以保证同步,图像无撕裂;

fifo读出的数据高低字节相互对调;

fifo里面数据量的判断作为启动dma写的条件之一。

(4)使用相应的上位机软件来测试,将视频数据通过上位机软件发送,可以看到视频在HDMI显示。

(5)在SDK中设计读回的函数,实现视频在算法处理后既能在HDMI显示,还能传回上位机。

图4-1 视频传回函数

(6)实际测试

5.至此便完成了本设计的所有内容。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲敲打打在创造

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值