admin 发表于 2019-4-20 20:54:38

【设计实例】基于SoC FPGA的Linux UDP图像发送。


如果您还没有注册本论坛,将无法下载论坛中附件,但是注册论坛非常简单,使用微   信 扫码即可注册。
也可以在小梅哥任意一个Q群内直接索取邀请码使用邀请码注册,小梅哥创建的任意一个群都可以。


以下代码为基本的Linux 使用UDP发送两个文件的图像数据到远端(192.168.0.106:6000)的程序,使用时,在DS-5或GCC下交叉编译得到可执行文件,然后拷贝到SoC 开发板中,同时,需要把附件的两bin格式图像二进制文件也拷贝到程序所在目录,然后执行,开发板就能不断的发送这两幅图像的数据到远端了。

需要注意的是,为了保证发送成功:
开发板的IP也需要设置为192.168.0.网段,比如设置为192.168.0.2
电脑的IP地址需要设置为192.168.0.168
图像接收软件的几个参数要与实际网络参数匹配(图像软件见下述附件)


如果图像软件运行失败,提示找不到mfcxxx.dll,请安装运行环境,百度下载 vcredist_x86安装就可以了


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <dirent.h>
#include <inttypes.h>
#include <sys/time.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include "math.h"
#include <string.h>

#include <linux/fb.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <signal.h>

char* ReadBmpFile(const char* szFile)
{
      FILE* fTmp = fopen(szFile, "rb");
      if (fTmp == NULL) return NULL;

      fseek(fTmp, 0, SEEK_END);
      int nLen = ftell(fTmp);
      if (nLen <= 0)
      {
                fclose(fTmp);
                return NULL;
      }

      char* szContent = (char*)malloc(nLen + 1);
      memset(szContent, 0, nLen + 1);
      fseek(fTmp, 0, SEEK_SET);
      char szTmp = { 0 };
      int nHaveRead = 0;
      while (!feof(fTmp))
      {
                int nRead = fread(szTmp, 1, 1024, fTmp);
                if (nRead <= 0) break;

                memcpy(szContent + nHaveRead, szTmp, nRead);
                nHaveRead += nRead;
      }
      fclose(fTmp);

      return szContent;
}

unsigned char STOP = 0;

void signalFunc(int _signal)
{
      STOP = 1;
}

int main(int argc, char ** argv) {

      signal(SIGINT, signalFunc);
      signal(SIGTERM, signalFunc);

      int nX = 640;
      int nY = 480;
      char* szBmp1 = ReadBmpFile("640_480_01.bin");
      if (NULL == szBmp1)
      {
                printf("read bmp file 1 error!");
                return 0;
      }
      char* szBmp2 = ReadBmpFile("640_480_02.bin");
      if (NULL == szBmp2)
      {
                printf("read bmp file 2 error!");
                return 0;
      }

      int retval;

    char buf;
    int socket_descriptor; //套接口描述字
      struct sockaddr_in address;//处理网络通信的地址
      int port=6000;
      bzero(&address,sizeof(address));
      address.sin_family=AF_INET;
      address.sin_addr.s_addr=inet_addr("192.168.0.106");//这里不一样
      address.sin_port=htons(port);
    unsigned char *p;
      //创建一个 UDP socket

      socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4SOCK_DGRAM 数据报套接字(UDP协议)

      int rbufsz = 5 * 1024 * 1024; //5M
      setsockopt(socket_descriptor, SOL_SOCKET, SO_RCVBUF, &rbufsz, sizeof(rbufsz));
      int wbufsz = 5 * 1024 * 1024; //5M
      setsockopt(socket_descriptor, SOL_SOCKET, SO_SNDBUF, &wbufsz, sizeof(wbufsz));

      int maxfdp;
      fd_set fds;
      fd_set fdsErr;
    struct timeval timeout = {1, 0};//设置select等待3秒,3秒轮询,非阻塞就置0
      int nSendFile = 0;
      long iter = 0;

    connect(socket_descriptor, (struct sockaddr *)&address,sizeof(address));

      while (!STOP)
      {

            FD_ZERO(&fds);//每次循环都要清空集合,否则不能检测描述符变化
                FD_SET(socket_descriptor, &fds);//添加描述符
                //FD_ZERO(&fdsErr);//每次循环都要清空集合,否则不能检测描述符变化
                //FD_SET(socket_descriptor, &fdsErr);//添加描述符
            maxfdp = socket_descriptor + 1;//描述符最大值加1
         // printf("1\n");
            retval = select(maxfdp, NULL, &fds, NULL, &timeout);
                if (retval <= 0)
                {
                        //usleep(1000);
                        continue;
                }
                p = (unsigned char *)((nSendFile == 0) ? szBmp1 : szBmp2);

                buf=iter >> 8;
                buf=iter & 0xff;
                //memcpy(&buf,p,1280);
                memcpy(&buf, p + iter * 1280, 1280);

            if(FD_ISSET(socket_descriptor,&fds))//测试skt是否可写,即网络上是否有数据
            {
                retval = write(socket_descriptor, buf, 1282);
                if(retval < 0){
                  perror("sendto error: ");
                  exit(1);
                }
            }

                iter++;

                if (iter > nY - 1)
                {
                        iter = 0;
                        nSendFile = (nSendFile + 1) % 2;
                        //usleep(1000);
                }
      }
      free(szBmp1);
      free(szBmp2);
      printf("app exit\n");

}



ccb97 发表于 2020-4-30 18:24:55

请问小梅哥有完整的工程吗,我不知道怎么在qsys中配置以太网,能发一份原工程吗
页: [1]
查看完整版本: 【设计实例】基于SoC FPGA的Linux UDP图像发送。