v831-T113-c-udp发送篇

又来分析udp,目标是从v831中获取到的图片信息发送给t113然后再屏幕上显示出来

挫折一

t113作为服务端,再接收到客户端发来的数据后会自动设置clinetaddr,那么我们就不再需要取从新aton这个ip地址了,直接使用clientaddr

int udp_send(void)
{
	// if (0 == inet_aton("192.168.1.118", &tSocketClientAddr.sin_addr)){
	// 	printf("invalid server_ip\n");
	// 	return -1;
	// }
	// printf("aton\n");
    iAddrLen = sizeof(struct sockaddr);
    iRecvLen = sendto(iSocketServer, "ok", 3, 0,
										 (struct sockaddr *)&tSocketClientAddr, iAddrLen);
    if (iRecvLen < 0)
    {
        printf("send error \n");
		return -1;
    }
	// printf("send\n");
    return 0;
}

int udp_rec(unsigned char *ucRecvBuf)
{
	int size;
    iAddrLen = sizeof(struct sockaddr);
    iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 240*240*3, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
    if (iRecvLen > 0)
    {
        ucRecvBuf[iRecvLen] = '\0';
        printf("Get Msg From %s : \n", inet_ntoa(tSocketClientAddr.sin_addr));
		for(size=0;size<iRecvLen;size++)
		{
			printf("%x",ucRecvBuf[size]);
		}
    }
    else{
        return -1;
    }
    return 0;
}

挫折二

sendto,这个函数再tcp中是会自动拆分的,因为最大数据包的问题,不可能全部数据一贞发送完,但是再udp中就不会自动拆分,所以在程序中我们应该手动拆分帧。根据百度的结果最大数据长度为:

int upd_send()
{
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	struct sockaddr_in tSocketClientAddr;

	libmaix_err_t err;

	
	int iRet;
	unsigned char ucSendBuf[1000];
	int iSendLen;
	int iAddrLen;

	printf("\r\nsize is %d\r\n",cam->fram_size);
	iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);

	tSocketServerAddr.sin_family      = AF_INET;
	tSocketServerAddr.sin_port        = htons(SERVER_PORT);  /* host to net, short */
 	//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
 	if (0 == inet_aton(ip_add, &tSocketServerAddr.sin_addr))
 	{
		printf("invalid server_ip\n");
		return -1;
	}
	memset(tSocketServerAddr.sin_zero, 0, 8);
	err = cam->start_capture(cam);
	if(err != LIBMAIX_ERR_NONE){
		printf("start capture fail: %s\n", libmaix_get_err_msg(err));
		return -1;
	}
	while (1)
	{
		err = cam->capture_image(cam,&img);
		if(err != LIBMAIX_ERR_NONE)
        {
            // not ready, sleep to release CPU
            if(err == LIBMAIX_ERR_NOT_READY)
            {
                usleep(20 * 1000);
                continue;
            }
            else
            {
                printf("capture fail: %s\n", libmaix_get_err_msg(err));
                break;
            }
        }
		iAddrLen = sizeof(struct sockaddr);
		printf("data size is %d\r\n",sizeof(img->data));
		iSendLen = sendto(iSocketClient, img->data,65507, 0,
								(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
		if (iSendLen <= 0)
		{
			close(iSocketClient);
			return -1;
		}
		while(( recvfrom(iSocketClient, ucSendBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen))<=0);
		if(strcmp(ucSendBuf,"ok"))
		{
			printf("no ok \n");
			printf("%s\n\n",ucSendBuf);
			close(iSocketClient);
			break;
		}
		printf("ok \n");
	}

	return 0;
}

挫折三

udp不要以数据的一贞为单位的发送再回复,因为这样会导致丢包而中断传输,所以尽量发送一次回复一次

t113:

#include "udp_lcd.h"


/* socket
 * bind
 * sendto/recvfrom
 */

#define SERVER_PORT 8888

struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iSocketServer;
int iSocketClient;
int iAddrLen;
int iRecvLen;

int udp_send(void)
{
	// if (0 == inet_aton("192.168.1.118", &tSocketClientAddr.sin_addr)){
	// 	printf("invalid server_ip\n");
	// 	return -1;
	// }
	// printf("aton\n");
    iAddrLen = sizeof(struct sockaddr);
    iRecvLen = sendto(iSocketServer, "ok", 3, 0,
										 (struct sockaddr *)&tSocketClientAddr, iAddrLen);
    if (iRecvLen < 0)
    {
        printf("send error \n");
		return -1;
    }
	// printf("send\n");
    return 0;
}

int udp_rec(unsigned char *ucRecvBuf)
{
	int size,total_size=0;
    iAddrLen = sizeof(struct sockaddr);
	iRecvLen = 0;
	while(total_size<(240*240*3))
	{
		iRecvLen = recvfrom(iSocketServer, ucRecvBuf+total_size, 240*240*3, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
		if (iRecvLen > 0){
			total_size+=iRecvLen;
		}
		else{
			printf("error\n\n",total_size);
			return -1;
		}
		udp_send();
	}
    return 0;
}

int udp_init()
{
	int iRet;

	//unsigned char ucRecvBuf[1000];

	int iClientNum = -1;
	
	iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);
	if (-1 == iSocketServer)
	{
		printf("socket error!\n");
		return -1;
	}

	tSocketServerAddr.sin_family      = AF_INET;
	tSocketServerAddr.sin_port        = htons(SERVER_PORT);  /* host to net, short */
 	tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
	memset(tSocketServerAddr.sin_zero, 0, 8);
	
	iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
	if (-1 == iRet)
	{
		printf("bind error!\n");
		return -1;
	}
	return 0;
}

int udp_end()
{
    close(iSocketServer);
    return 0;
}

v831

int udp_start(void){
		iAddrLen = sizeof(struct sockaddr);
	while(total_size<(240*240*3)){
		if(((240*240*3)-total_size)>=65507){
			iSendLen = sendto(iSocketClient,( img2->data)+total_size,65507, 0,
									(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
		}
		else{
			iSendLen = sendto(iSocketClient,( img2->data)+total_size,(240*240*3)%65507, 0,
					(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
		}
		if (iSendLen <= 0)
		{
			printf("\n failed send\n");
			close(iSocketClient);
			return -1;
		}
		total_size+=iSendLen;

	while(( recvfrom(iSocketClient, ucSendBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen))<=0);
		if(strcmp(ucSendBuf,"ok"))
		{
			printf("no ok \n");
			printf("%s\n\n",ucSendBuf);
			close(iSocketClient);
			break;
		}
	}
total_size=0;
return 0;
}

挫折四

大小端的问题,这个问题困扰了我一天了,v831发送的数据没有错误,只不过在强制转换的时候要注意大小端的问题,这是有关大小端的一篇文章

我的这块板子估计在转换的时候,char转换为int,由于大小端的问题,应该是大端模式,低地址放高数据。

改之后的代码
 void rgb_to_argb(unsigned char *rgb,unsigned char *argb,int size)
{
    int i; 
    printf("\r\ncolor is %8lx\r\n",*(unsigned int *)rgb);
    for(i=0;i<(size/3);i++)
    {
        *(argb+3)=(unsigned char)0xff;
      
        *(argb)=(*(rgb+2));
        *(argb+1)=(*(rgb+1));
        *(argb+2)=(*(rgb+0));
        argb+=4;
        rgb+=3;
       
    }
}

主体的代码

t113:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "linux/fb.h"
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include "udp_lcd.h"

uint32_t fb_line,fb_byte_per,fb_all_bit;
unsigned char *fb_base;
static struct fb_var_screeninfo var;

void rgb_to_argb(unsigned char *rgb,unsigned char *argb,int size)
{
    int i; 
    for(i=0;i<(size/3);i++)
    {
        *(argb+3)=(unsigned char)0xff;
      
        *(argb)=(*(rgb+2));
        *(argb+1)=(*(rgb+1));
        *(argb+2)=(*(rgb+0));
        argb+=4;
        rgb+=3;
       
    }
}

void lcd_flash(unsigned int  x,unsigned int y,int endx,int endy,unsigned int *buffer,unsigned int size)
{
    unsigned int i;
    unsigned int *fb_test=(unsigned int *)fb_base;
    fb_test+=(unsigned int)(x+fb_line*y/4);//fb_line*0/4;//
    for(i=0;i<size;i++)
    {
        *fb_test = (unsigned int)buffer[i];
        // printf("\r\ncolor2 is %8.lx\r\n",buffer[i]);
        if(!((i+1)%(endx+1))&&(i!=0)){
            fb_test+=(unsigned int)(fb_line/4-endx);//800-239;//
        }
        else{
            fb_test++;
        }
        // if(i==239*2)
        // break;
       
    }
}

int main()
{
    unsigned char buf[240*240*4];
    unsigned char rgbbuf[240*240*3];
    int fb_handle;
    fb_handle = open("/dev/fb0",O_RDWR);
    if(fb_handle < 0)
    {
        return -1;
    }
    memset(buf,-1,sizeof(buf));
    if(ioctl(fb_handle,FBIOGET_VSCREENINFO,&var))//使用获取动态数据的标志符从驱动获取屏幕数据
    {
        return -1;
    }
    ////////获取屏幕的数据
    fb_line = var.xres * var.bits_per_pixel / 8;//长度
    fb_byte_per = var.bits_per_pixel / 8;
    fb_all_bit = var.xres * var.yres * var.bits_per_pixel / 8;//总贞数
    ////////对文件进行映射
    fb_base = (unsigned char *)mmap(NULL , fb_all_bit, PROT_READ | PROT_WRITE, MAP_SHARED, fb_handle, 0);
    if(fb_base == (unsigned char *)-1)
    {
        printf("failed to mmap");
        return -1;
    }
    printf("bpp is %d\r\n all is %d\r\n x is %d y is %d\r\n",var.bits_per_pixel,var.xres*var.yres,var.xres,var.yres);
    udp_init();
    lcd_flash(10,0,239,239,buf,240*240);
    while(1){
        if(!udp_rec(rgbbuf))
        {
            rgb_to_argb(rgbbuf,(unsigned int *)buf,240*240*3);
            lcd_flash(10,0,239,239,(unsigned int *)buf,240*240);
        }
        else
        {}
    }
    
    //memset(fb_base, 0xf0, fb_all_bit);//清个白屏试试
    udp_end();
    munmap(fb_base,fb_all_bit);
    close(fb_handle);
}

v831:

#include "stdio.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

#include "global_config.h"
#include "global_build_info_time.h"
#include "global_build_info_version.h"

#include "main.h"
#include <sys/time.h>
#include <unistd.h>
#include <math.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>


#include "libmaix_cam.h"
#include "libmaix_image.h"
#include "libmaix_disp.h"
#include "libmaix_cv_image.h"

#define ip_add "192.168.1.124"
#define SERVER_PORT 8888


struct libmaix_cam* cam = NULL;
libmaix_image_t* img;
libmaix_image_t *t = NULL;
libmaix_image_t *img2= NULL;

int iSendLen;
int iAddrLen;
int total_size=0;
int iSocketClient;
unsigned char ucSendBuf[1000];

struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;


int camera_init(void){	
}

int camera_end(void){
}

int udp_start(void){
		iAddrLen = sizeof(struct sockaddr);
	while(total_size<(240*240*3)){
		if(((240*240*3)-total_size)>=65507){
			iSendLen = sendto(iSocketClient,( img2->data)+total_size,65507, 0,
									(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
		}
		else{
			iSendLen = sendto(iSocketClient,( img2->data)+total_size,(240*240*3)%65507, 0,
					(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
		}
		if (iSendLen <= 0)
		{
			printf("\n failed send\n");
			close(iSocketClient);
			return -1;
		}
		total_size+=iSendLen;

	while(( recvfrom(iSocketClient, ucSendBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen))<=0);
		if(strcmp(ucSendBuf,"ok"))
		{
			printf("no ok \n");
			printf("%s\n\n",ucSendBuf);
			close(iSocketClient);
			break;
		}
	}
total_size=0;
return 0;
}


int upd_send()
{

	cam = libmaix_cam_create(0, 240, 240, 1, 0);
	libmaix_camera_module_init();
	libmaix_image_module_init();


	struct libmaix_disp* disp = libmaix_disp_create(0);
	disp->height=240;disp->width=240;
    
	libmaix_err_t err;
	
	int iRet;




	printf("\r\nsize is %d\r\n",cam->fram_size);
	iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);

	tSocketServerAddr.sin_family      = AF_INET;
	tSocketServerAddr.sin_port        = htons(SERVER_PORT);  /* host to net, short */
 	//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
 	if (0 == inet_aton(ip_add, &tSocketServerAddr.sin_addr))
 	{
		printf("invalid server_ip\n");
		return -1;
	}
	memset(tSocketServerAddr.sin_zero, 0, 8);
	err = cam->start_capture(cam);


	libmaix_cam_t* cam2 = libmaix_cam_create(1, 240, 240, 1, 0);
	err = cam2->start_capture(cam2);
	if(err != LIBMAIX_ERR_NONE){
		printf("start capture fail: %s\n", libmaix_get_err_msg(err));
		return -1;
	}
	while (1)
	{
		err = cam->capture_image(cam,&img2);
		err = cam2->capture_image(cam2,&t);
		
		if(err != LIBMAIX_ERR_NONE)
        {
            // not ready, sleep to release CPU
            if(err == LIBMAIX_ERR_NOT_READY)
            {
                usleep(20 * 1000);
                continue;
            }
            else
            {
                printf("capture fail: %s\n", libmaix_get_err_msg(err));
                break;
            }
        }
		// for(i=0;i<57600;i++){
		// 	libmaix_cv_image_set_pixel(img2,i/240,i%240,MaixColor(0,0xff,0));
		// }
		// printf("\r\ncolor is %8x\r\n",*(unsigned int *)(img2->data));
		udp_start();
		disp->draw_image(disp,img2);

	}
	libmaix_image_destroy(&img2);
	libmaix_image_destroy(&img);
	libmaix_cam_destroy(&cam);
	libmaix_disp_destroy(&disp);
	libmaix_cam_destroy(&cam2);
	libmaix_image_destroy(&t);

	libmaix_image_module_deinit();
	libmaix_camera_module_deinit();
	return 0;
}

int main(int argc, char* argv[])
{
	camera_init();
    upd_send();
	camera_end();
    return 0;
}

 

posted @ 2023-07-31 15:01  悠闲的小莫  阅读(43)  评论(0编辑  收藏  举报