⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcv.c

📁 linux 串口接受发送程序
💻 C
字号:
#include     <stdio.h>   #include     <stdlib.h>  #include     <unistd.h> #include     <sys/types.h>#include     <sys/stat.h>  #include     <fcntl.h>      #include     <termios.h>  #include     <errno.h>     #define BL_NO_ERR            1#define BL_ERR_OPEN_COMM   100#define BL_ERR_OPEN_FILE     101#define BL_ERR_FILE_LENGTH   102#define TIMEOUT_SEC(len,baud)  ((len)*20/(baud))#define TIMEOUT_USEC      500000#define RCVED_NAN         0x0#define RCVED_LEN         0x1#define RCVING_DATA       0x2#define CH_ACK_OK         0x5A#define CH_ACK_ERR        0xAA#define CH_PACK_LEN       0x55#define CH_PACK_DATA      0x5A#define CH_ACK_LEN_OK      0x55#define CH_ACK_DATA_OK      0x5Aint speed_arr[ ] = { B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,		         B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300 };int name_arr[ ] = { 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300,		         115200, 38400, 19200, 9600, 4800, 2400, 1200, 300 };int fd_com;                     // the file descriptor of serial comint fd_file;                      // the file descriptor of save file				 int set_com (int fd, int speed, int fctl, int databits, int stopbits, int parity){	struct termios options;		bzero(&options,sizeof(options));	cfmakeraw(&options);		cfsetispeed(&options, speed);	cfsetospeed(&options, speed);		options.c_cflag |= CLOCAL;	options.c_cflag |= CREAD;		switch (fctl) {                             // flow control		case 0:			options.c_cflag &= ~CRTSCTS;			break;		case 1:			options.c_cflag |= CRTSCTS;			break;		case 2:			options.c_iflag |= (IXON | IXOFF | IXANY);			break;		default:			printf("flow ctl err!\n");			return (-1);	} 		options.c_cflag &= ~CSIZE;                  // data bits	switch (databits) {		case 5:			options.c_cflag |= CS5;			break;		case 6:			options.c_cflag |= CS6;			break;		case 7:			options.c_cflag |= CS7;			break;		case 8:			options.c_cflag |= CS8;			break;		default:			printf("unsupported data size!\n");			return (-1);	}	switch (parity) {		case 'n':		case 'N':			options.c_cflag &= ~PARENB;   /* Clear parity enable */			break;		case 'o':		case 'O':			options.c_cflag |= (PARODD | PARENB); 			break;		case 'e':		case 'E':			options.c_cflag |= PARENB;     /* Enable parity */			options.c_cflag &= ~PARODD;  			break;		default:			printf("unsupported parity!\n");			return (-1);	}	switch (stopbits) {		case 1:			options.c_cflag &= ~CSTOPB;			break;		case 2:			options.c_cflag |= CSTOPB;			break;		default:			printf("unsupported stop bits!\n");			return (-1);	}		options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* set to raw input and output */	options.c_oflag &= ~OPOST;			options.c_cc[VTIME] = 0;                     // 0 ms	options.c_cc[VMIN] = 1; 	if (tcsetattr(fd,TCSANOW,&options) != 0) {       /*Update the options and do it NOW */		printf("set com cfg err!\n");		return (-1);	}	tcflush(fd,TCIOFLUSH);                      // fulshs data received but not read, and data written but not transmitted.		return 0;}int read_n (int fd, void *buf, int len){	int  cou = 0;	int  ret = 0;	fd_set  fs_read;	struct timeval  tv_timeout;		FD_ZERO (&fs_read);	FD_SET (fd, &fs_read);	tv_timeout.tv_sec = TIMEOUT_SEC (len, 115200);	tv_timeout.tv_usec = TIMEOUT_USEC;	while (len > 0) {		if (select (fd+1, &fs_read, NULL, NULL, &tv_timeout)) { //检查设备是否可读			tv_timeout.tv_usec = 20000;			ret = read (fd, (char*)buf+cou, len);			if (ret < 1) {				break;			}			cou += ret;			len  -= ret;		} else {			break;		}	}	return cou;}int write_n (int fd, void *buf, int len){	int  cou = 0;	int  ret = 0;   	fd_set  fs_write;	struct timeval  tv_timeout;	FD_ZERO (&fs_write);	FD_SET (fd, &fs_write);	tv_timeout.tv_sec = TIMEOUT_SEC (len, 115200);	tv_timeout.tv_usec = TIMEOUT_USEC;		while (len > 0) {		if (select (fd + 1, NULL, &fs_write, NULL, &tv_timeout)) {			tv_timeout.tv_usec = 20000;			ret = write(fd, (char*)buf+cou, len);			if (ret < 1) {				break;			}			cou += ret;			len -= ret;		} else {			tcflush(fd, TCOFLUSH);			return -1;		}	}	return cou;}int init_file_transfer (void){  	fd_com = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); 		if (-1 == fd_com) {		printf("can't open serial port!\n");		return (BL_ERR_OPEN_COMM);	}		if (-1 == set_com (fd_com, B115200, 0, 8, 1, 'n')) {		printf("set serial err!\n");		return (BL_ERR_OPEN_COMM);	}	//fd_file = open("/qte/myfile/down/mydata.dat", O_RDWR | O_CREAT);	fd_file = open("/home/fa/down/mydata.dat", O_RDWR | O_CREAT);		if (fd_file == -1) {		printf("can't open file!\n");		close(fd_com);		return BL_ERR_OPEN_FILE; 	}		return (BL_NO_ERR);}int save_transfer_file (unsigned long total_len){	char buf[1030];	unsigned int save_len = 0;	int len;	int fd_file_sbr;	unsigned long file_len = 0;	char path[30]; 		fsync(fd_file);	lseek(fd_file, 0, SEEK_SET);	while (save_len < total_len) {		len = read_n(fd_file, buf, 19);		if (len != 19) {			return (-1);		}		if (buf[0] != 'S') {			return (-2);		}			strcpy(path, "/home/fa/down/");		//strcpy(path, "/qte/myfile/down/");		strcat(path, &buf[1]);          //file path				fd_file_sbr = open(path, O_RDWR | O_CREAT | O_TRUNC);		if (-1 == fd_file_sbr) {			return (-3);		}		//file_len = *(unsigned long*)&buf[15];		file_len = buf[15] | (buf[16] << 8) | (buf[17] << 16) | (buf[18] << 24); 		//printf("filelen = %d\n",file_len);		save_len += (file_len + 20);		while (file_len > 0) {			if (file_len >= 1024) {				len = 1024;			} else {				len = file_len;			}				if (len != read_n(fd_file, buf, len)) {				close(fd_file_sbr);				return (-4);				}			write_n(fd_file_sbr, buf, len);			file_len -= len;		}				if (1 != read_n(fd_file, buf, 1)) {			close(fd_file_sbr);			return -5;			}		close(fd_file_sbr);				if (buf[0] != 'E') {			return -6;			}	}	return total_len;}void end_file_transfer (void){	close(fd_file);	close(fd_com);	}int rcv_pack_head (unsigned char* head){	if (1 == read_n(fd_com, head, 1)) {		return 0;	}	return -1;	}unsigned char cal_chksum (unsigned char* buf, int len){	unsigned char sum = 0;	int i;		for (i = 0; i < len; i++) {		sum += buf[i];	}		return sum;	}static unsigned char pack_no = 0;	unsigned int rcv_lenth_pack (void){	unsigned char buf[255];	unsigned char ch_ack;	unsigned short len;		if (2 == read_n (fd_com, &len, 2)) {		if (len >= 5 && len == read_n(fd_com, buf, len)) {			//printf("rcved lenth = %d!\n", *(unsigned long*)buf);			if (buf[len-1] == cal_chksum(buf, len-1)) {   				ch_ack = CH_ACK_LEN_OK;				//printf("chksun ok!\n");				if (1 == write_n(fd_com, &ch_ack, 1)) {					pack_no = 0;					return *(unsigned long*)buf;				} 			} else {				ch_ack = CH_ACK_ERR;					write_n(fd_com, &ch_ack, 1);			}			}	}	return 0;	}unsigned int rcv_data_pack (void){	unsigned char buf[2060];	unsigned char ch_ack;	unsigned short len;	if (2 == read_n (fd_com, &len, 2)) {		//printf("len = %d\n",len);		if (len >= 3 && len == read_n(fd_com, buf, len)) {			//printf("rcved data\n",len);			if (buf[len-1] == cal_chksum(buf, len-1)) {   //校验成功				ch_ack = CH_ACK_DATA_OK;				if (1 == write_n(fd_com, &ch_ack, 1)) {					//printf("snd checksum OK!\n");					if (buf[0] == pack_no) {						; //rcved repeat pack					} else if (buf[0] == (unsigned char)(pack_no+1)) {						if ((len-2) != write(fd_file, &buf[1], len-2)) {							printf("write file err!\n");						}						pack_no++;						return (len-2);					} else {						printf("rcved pack_no err,pack_no = %d, rcv_no = %d!\n",pack_no,buf[0]);					}				} 			} else {				//printf("checksum err!\n");				ch_ack = CH_ACK_ERR;				write_n(fd_com, &ch_ack, 1);			}		}	}	return 0;}int main (void){	int status = RCVED_NAN;	unsigned char head;	unsigned long total_len,received_len,len;	int percent, cnt = 0;		if (BL_NO_ERR != init_file_transfer()) 	{		printf("init file err!\n");		return (-1);	}		status = RCVED_NAN;	while (1) {		if (-1 == rcv_pack_head(&head)) {			cnt ++;			if (status == RCVED_NAN && cnt < 100) {				continue;			} else if (status == RCVED_LEN && cnt < 20) {				continue;			} else if (status == RCVING_DATA && cnt < 20) {				continue;			} else {				printf("rcv packhead timeout!\n");				break;			}		} else {			cnt = 0;		}		//printf("head = %2x\n",head);		switch (head) {			case CH_PACK_LEN:				if (status != RCVING_DATA) {					total_len = rcv_lenth_pack();						if (total_len > 0) {						status = RCVED_LEN;						received_len = 0;					} else {						total_len = 0;						received_len = 0;						status = RCVED_NAN;						}				}				break;						case CH_PACK_DATA:				if (status == RCVED_LEN || status == RCVING_DATA) {									len = rcv_data_pack();					if (len > 0) {						received_len += len;						status = RCVING_DATA;						//printf("rcved len = %d\n", received_len);						len = 100*received_len/total_len;						if (len != percent) {							percent = len;							printf("receive percent = %d%\n", percent);						}					}				}				break;					default: 				printf("unexpected msg!\n");				tcflush(fd_com, TCIFLUSH); 				break;		}		if (total_len > 0 && received_len >= total_len) {			if (0 >= save_transfer_file (total_len))				printf("save data err!\n");			printf("over,received len = %d!\n", received_len);				break;		}	}	end_file_transfer();//save file and close comm port	return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -