diff options
| author | Pavel Vymetálek <pavel@vym.cz> | 2019-02-19 15:43:42 +0100 | 
|---|---|---|
| committer | Pavel Vymetálek <pavel@vym.cz> | 2019-02-19 15:43:42 +0100 | 
| commit | fc1b66cc509b1a38a0733049cc522acc921f521a (patch) | |
| tree | a2e02bccaf622db954ee88b92afdb90c0fdffec7 | |
| parent | 763b0e4a17aad661705ed333f57cb989b5ac31c3 (diff) | |
| download | sercp-pc-fc1b66cc509b1a38a0733049cc522acc921f521a.tar.gz | |
sercp možno přeložit pro Win64 a Win32
- přidán soubor sercp.res s podpisem exáče :-)
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | sercp.c | 356 | 
2 files changed, 295 insertions, 75 deletions
| @@ -1,9 +1,21 @@  PROJECT=sercp -all:	$(PROJECT) +all:	$(PROJECT) $(PROJECT).w32 $(PROJECT).w64  sercp:	$(PROJECT).c  	gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 +sercp.w64: $(PROJECT).c +	rm -f $(PROJECT).res +	x86_64-w64-mingw32-windres -i $(PROJECT).rc --input-format=rc --codepage=65001 -o $(PROJECT).res -O coff +	x86_64-w64-mingw32-gcc $(PROJECT).c $(PROJECT).res -o $(PROJECT).exe   -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 +	x86_64-w64-mingw32-strip $(PROJECT).exe + +sercp.w32: $(PROJECT).c +	rm -f $(PROJECT).res +	i686-w64-mingw32-windres -i $(PROJECT).rc --input-format=rc --codepage=65001 -o $(PROJECT).res -O coff +	i686-w64-mingw32-gcc $(PROJECT).res $(PROJECT).c -o $(PROJECT)32.exe -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 +	i686-w64-mingw32-strip $(PROJECT)32.exe +  debug:	$(PROJECT).c  	gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -g -O0 @@ -1,19 +1,45 @@ -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdint.h> -#include <libgen.h> -#include <getopt.h> -#include <termios.h> -#include <error.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/signal.h> -#include <signal.h> -#include <fcntl.h> -#include <poll.h> + + +#ifdef __WIN32 +// 	#include <stdio.h> +// 	#include <unistd.h> +// 	#include <stdlib.h> +// 	#include <string.h> + +	#include <stdio.h> +	#include <stdint.h> +	#include <io.h> +	#include <fcntl.h> +	#include <windows.h> +	#include <getopt.h> +	#include <signal.h> +	#include <fcntl.h> +	#include <errno.h> +	#include <unistd.h> +	#include <libgen.h> +	#include <sys/stat.h> +	#include <error.h> + +#else + +	#include <stdio.h> +	#include <unistd.h> +	#include <stdlib.h> +	#include <string.h> +	#include <errno.h> +	#include <stdint.h> +	#include <libgen.h> +	#include <getopt.h> +	#include <termios.h> +	#include <error.h> +	#include <sys/stat.h> +	#include <sys/ioctl.h> +	#include <sys/signal.h> +	#include <signal.h> +	#include <fcntl.h> +	#include <poll.h> +#endif +  #define false 0  #define FALSE 0 @@ -22,7 +48,6 @@  const char* _version = "v0.2";  // SERIAL -char MODEMDEVICE[64];  FILE *tapout_fd = NULL;  int is_outfile = 0;  int baud_rate = 0; @@ -34,18 +59,33 @@ unsigned char buff[32768];  unsigned char *p_buff;  unsigned int is_continue = 1;  unsigned int is_binary = 0; -struct pollfd spolfd_serial[1];	  // pole descriptoru pro poll  static int inp_indx = 0; -int serial_fd; -size_t out_indx; -struct sigaction saterm;           /* definition of signal action */ +size_t out_indx;  float width;		// width of terminal  long pos = 0;  int scp = 0;  int is_scp_read = 0; +char MODEMDEVICE[64] = { +#ifdef __WIN32 +	"\\\\.\\COM1" +#else +	"/dev/ttyUSB0" +#endif +}; + +#ifdef __WIN32 +	static HANDLE serial_fd; +#else +	int serial_fd; +	struct sigaction saterm;           /* definition of signal action */ +	struct pollfd spolfd_serial[1];	  // pole descriptoru pro poll +#endif + + +  typedef struct {  	uint16_t block_len;  	uint8_t  block_xor; @@ -72,7 +112,11 @@ void usage(void) {  	printf ("Usage:\nsercp [-v] [-h] -d /dev/serial [-b baud_rate] [-w time] [-r] <filename>\n");  	printf ("\t-v, --version\tShow version info\n");  	printf ("\t-h, --help\tShow this text\n"); -	printf ("\t-d, --device\tCommunication device\n"); +#ifdef __WIN32 +	printf ("\t-d, --device\tSerial com port\n"); +#else +	printf ("\t-d, --device\tSerial communication device\n"); +#endif  	printf ("\t-b, --baud\tSet the communication speed. Default 38400Bd\n");  	printf ("\t-w, --wait\tWaiting in milliseconds between transmitted blocks. Default is -w 800 milliseconds\n");  	printf ("\t-r, --read\tRead file from serial port\n"); @@ -101,8 +145,13 @@ void TestArgs (int argc, char *argv[])  		}  		switch (c) {  			case 'd': -				strncpy(MODEMDEVICE, optarg, strlen(optarg)); -				// 				printf ("Serial port: %s\n", MODEMDEVICE); +#ifdef __WIN32 +				sprintf(MODEMDEVICE, "\\\\.\\%s", optarg); +#else +// 				strncpy(MODEMDEVICE, optarg, strlen(optarg)); +				sprintf(MODEMDEVICE, "%s", optarg); +#endif +								printf ("Serial port: %s\n", MODEMDEVICE);  				break;  			case 'b':  				baud_rate = atoi(optarg); @@ -134,8 +183,42 @@ void TestArgs (int argc, char *argv[])  } -/************************************************************************/ +//***************************************************************************** +// +// uSleep win32 implementation + +void uSleep(int waitTime) { +	#ifdef __WIN32 +	__int64 time1 = 0, time2 = 0, freq = 0; + +	QueryPerformanceCounter((LARGE_INTEGER *) &time1); +	QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + +	do { +		QueryPerformanceCounter((LARGE_INTEGER *) &time2); +	} while ((time2 - time1) < waitTime); +	#else +	uSleep(waitTime); +	#endif +} + +// cross-platform sleep function +void sleep_ms(int milliseconds) { +#ifdef WIN32 +	Sleep(milliseconds); +// #elif _POSIX_C_SOURCE >= 199309L +// 	struct timespec ts; +// 	ts.tv_sec = milliseconds / 1000; +// 	ts.tv_nsec = (milliseconds % 1000) * 1000000; +// 	nanosleep(&ts, NULL); +#else +	usleep(milliseconds * 1000); +#endif +} + + +/************************************************************************/  void signal_handler_sigterm (int status) {  	// CTRL+C pressed  	is_continue = 0; 	// do not continue @@ -143,9 +226,13 @@ void signal_handler_sigterm (int status) {  /************************************************************************/  int GetTerminalWidth(void) { +#ifdef __WIN32 +	return (80); +#else  	struct winsize termsize;  	ioctl (STDOUT_FILENO, TIOCGWINSZ, &termsize);  	return (termsize.ws_col); +#endif  }  #define PROGRESS_PERCENT	0 @@ -265,7 +352,7 @@ uint32_t GetOverallLen(FILEINFO *p_fi) {  }  /************************************************************************/ -void RecvSCP(void) { +void sercpRecv(void) {  	int recv_phase = 0;			// 0 - fileinfo, 1 - blok 16kiB, 2 - posledni blok  	uint8_t block_index = 0;  	int result; @@ -277,6 +364,7 @@ void RecvSCP(void) {  	uint32_t overall_length = 0;		// celkova delka souboru  	uint32_t recv_length = 0;			// zatim prijatych dat ze souboru  	int err; +	unsigned long ulNumBytes;  	FILEINFO *p_fileinfo = &fileinfo;  	unsigned char *p_buff = buff; @@ -284,16 +372,25 @@ void RecvSCP(void) {  	memset (p_fileinfo, 0, sizeof(fileinfo));  	while (is_continue) { +		#ifndef __WIN32  		result = poll (spolfd_serial, 1, 200);		// 200ms timeout  		if (result == 0) {  			// nic neprislo  			continue;  		} +		#endif  		switch (recv_phase) {  			case 0:  				// prijem fileinfo -				if (spolfd_serial[0].revents & POLLIN) { +// 				if (spolfd_serial[0].revents & POLLIN) { +#ifdef __WIN32 +					sleep_ms(10); +					ReadFile(serial_fd, p_buff,  sizeof(fileinfo), &ulNumBytes, NULL); +					len = (uint16_t) ulNumBytes; +#else +					sleep_ms(10);  					len = read (serial_fd, p_buff, sizeof(fileinfo)); +#endif  					p_buff += len;  					length += len;  					if (length == sizeof(fileinfo)) { @@ -307,12 +404,16 @@ void RecvSCP(void) {  							p_buff = buff;			// buffer na zacatek  							length = 0;  							expected_len = p_fileinfo->fi_blocks[block_index].block_len; - - -							tapout_fd = fopen ((char*)p_fileinfo->fi_name, "w"); +							tapout_fd = fopen ((char*)p_fileinfo->fi_name, "wb");  							if (tapout_fd == NULL) {  								err = errno; +								#ifdef __WIN32 +								printf ("can't open output file"); +								exit (EXIT_FAILURE); + +								#else  								error (1, err, "can't open output file"); +								#endif  							}  						} else {  							printf("Fileinfo neni v cajku. Koncim...\n"); @@ -320,16 +421,30 @@ void RecvSCP(void) {  						}  						break;  					} else if (length > sizeof(fileinfo)){ +#ifdef __WIN32 +						ReadFile(serial_fd, p_buff,  sizeof(fileinfo), &ulNumBytes, NULL); +						len = (uint16_t)ulNumBytes; +#else +  						len = read (serial_fd, p_buff, sizeof(fileinfo)); +#endif  						printf("Nejaky bordel. Koncim...\n");  						break;  					} -				} +// 				}  				break;  			case 1:  				// prijem datoveho bloku - max. delka 16kiB -				if (spolfd_serial[0].revents & POLLIN) { +// 				if (spolfd_serial[0].revents & POLLIN) { +#ifdef __WIN32 +					ReadFile(serial_fd, p_buff, expected_len, &ulNumBytes, NULL); +					len = (uint16_t)ulNumBytes; +					sleep_ms(10); +#else  					len = read (serial_fd, p_buff, expected_len); +					sleep_ms(10); +#endif +// 					printf ("read len: %d\n", len);  					p_buff += len;  					expected_len -= len;  					length += len; @@ -353,19 +468,28 @@ void RecvSCP(void) {  						is_continue = 0;  						break;  					} -				} else if (length > 16384) { -						len = read (serial_fd, p_buff, 16384); -						printf("Nejaky bordel. Koncim...\n"); -						break; -				} +// 				} +				/*else if (length > 16384) { +#ifdef __WIN32 +					ReadFile(serial_fd, p_buff, 16384, &ulNumBytes, NULL); +					len = (uint16_t)ulNumBytes; +#else +					len = read (serial_fd, p_buff, 16384); +#endif +					printf("Nejaky bordel. Koncim...\n"); +					break; +				}*/  			}  	} -	if (tapout_fd) fclose (tapout_fd); +	if (tapout_fd) { +		fflush (tapout_fd); +		fclose (tapout_fd); +	}  	printf ("\n\nulozeno...\n");  }  /************************************************************************/ -void SendSCP(void) { +void sercpSend(void) {  	FILE *tap_fd;  	char *bname, *basec;			// pinter na kopii nazvu souboru - basename  	char *shortfilename; @@ -380,18 +504,23 @@ void SendSCP(void) {  	uint32_t len_sent;  	uint16_t sent_size;  	uint32_t overall_sent; +	unsigned long ulNumBytes;  	no = stat(sercp_file, &st);  	if (no != 0) {  		err = errno; -		error(1, err, "can't stat input file"); +// 		error(1, err, "can't stat input file"); +		printf ("can't stat input file\n"); +		exit (EXIT_FAILURE);  	} -	tap_fd = fopen(sercp_file, "r"); +	tap_fd = fopen(sercp_file, "rb");  	if (tap_fd == NULL)	{  		err = errno; -		error(1, err, "can't open input file"); +// 		error(1, err, "can't open input file"); +		printf ("can't open input file\n"); +		exit (EXIT_FAILURE);  	}  	if (st.st_size == 0) {  		printf ("Zero length of file. End\n"); @@ -424,11 +553,16 @@ void SendSCP(void) {  	p_fileinfo->fi_numblocks = num_blocks;  	p_fileinfo->length = num_blocks*4 + 85;  	CountFileInfoChecksum(p_fileinfo); +#ifdef __WIN32 +	WriteFile(serial_fd, (void*)p_fileinfo, sizeof(fileinfo), &ulNumBytes, NULL); +#else  	odeslano = write (serial_fd, (void*)p_fileinfo, sizeof(fileinfo));  	tcdrain(serial_fd); +#endif  	printf("Fileinfo sent with filename: %s\n", bname);  	// TODO Cekat pauzu mezi bloky -	usleep (wait_ms * 1000); +// 	uSleep (wait_ms * 1000); +	sleep_ms(wait_ms);  	rewind(tap_fd);				// prenaseny soubor na zacatek  	file_len = (uint32_t) st.st_size; @@ -439,8 +573,14 @@ void SendSCP(void) {  		sent_size = 256;  		len_sent = len;  		while (len_sent && is_continue) { +#ifdef __WIN32 +			WriteFile(serial_fd, (void*)p_buff, sent_size, &ulNumBytes, NULL); +			odeslano = (size_t)ulNumBytes; +// 			sleep_ms(wait_ms); +#else  			odeslano = write (serial_fd, (void*)p_buff, sent_size);  			tcdrain(serial_fd); +#endif  			p_buff += odeslano;  			overall_sent += odeslano;  			len_sent -= odeslano; @@ -449,32 +589,57 @@ void SendSCP(void) {  			}  			DoProgress(overall_sent, st.st_size, PROGRESS_PERCENT);  		} -		usleep (wait_ms * 1000); +// 		uSleep (wait_ms * 1000); +		sleep_ms(wait_ms); +  		file_len -= len;  	}  	printf("\nFile sent...\n");  	fclose(tap_fd);  } -/************************************************************************/ -/************************************************************************/ -int main(int argc, char** argv, char** env) -{ -	// osetreni breaku ^C -	saterm.sa_handler = signal_handler_sigterm; -	saterm.sa_flags = 0; -	sigaction (SIGINT, &saterm, NULL); -	width = GetTerminalWidth(); +int OpenUart() { +#ifdef __WIN32 +	DCB sDCB; +	COMMTIMEOUTS sCommTimeouts; -	// nastaveni serioveho portu -	struct termios oldtio, newtio; -	inp_indx = 0; -	if (argc < 2) { -		printf("You must specify the Serial device and file\n"); -		usage(); -		exit(1); +	serial_fd = CreateFile(MODEMDEVICE, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); +	if (serial_fd == INVALID_HANDLE_VALUE) { +		return (-1);  	} -	TestArgs (argc, argv); +	if (GetCommState(serial_fd, &sDCB) == 0) { +		return (-1); +	} +	if (baud_rate == 0) baud_rate = 38400; +	sDCB.BaudRate = baud_rate; +	sDCB.ByteSize = 8; +	sDCB.Parity = NOPARITY; +	sDCB.fBinary = TRUE; +	sDCB.StopBits = ONESTOPBIT; +	sDCB.fAbortOnError = TRUE; +	sDCB.fOutxCtsFlow = FALSE; +	sDCB.fOutxDsrFlow = FALSE; +// 	sDCB.fDtrControl = DTR_CONTROL_ENABLE; +	if (SetCommState(serial_fd, &sDCB) == 0) { +		return (-1); +	} + +	if (GetCommTimeouts(serial_fd, &sCommTimeouts) == 0) { +		return (-1); +	} + +	sCommTimeouts.ReadIntervalTimeout = MAXDWORD;	//80 +	sCommTimeouts.ReadTotalTimeoutConstant = 00; +	sCommTimeouts.ReadTotalTimeoutMultiplier = 00; +	sCommTimeouts.WriteTotalTimeoutConstant = 80; +	sCommTimeouts.WriteTotalTimeoutMultiplier = 80; + +	if (SetCommTimeouts(serial_fd, &sCommTimeouts) == 0) { +		return (-1); +	} +	return (0); +#else +	struct termios oldtio, newtio;  	/* open the device to be non-blocking (read will return immediatly) */  	serial_fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);  	if (serial_fd < 0) { @@ -484,33 +649,33 @@ int main(int argc, char** argv, char** env)  	tcgetattr(serial_fd, &oldtio); /* save current port settings */  	switch (baud_rate){  		case 115200: -			newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD; +			newtio.c_cflag = B115200;  			break;  		case 57600: -			newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD; +			newtio.c_cflag = B57600;  			break;  		default:  			baud_rate = 38400;  		case 38400: -			newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD;	// dva stopbity jsou nastaveny vsude, ale tady ne +			newtio.c_cflag = B38400;  			break;  		case 19200: -			newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD; +			newtio.c_cflag = B19200;  			break;  		case 9600: -			newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD; +			newtio.c_cflag = B9600;  			break;  		case 4800: -			newtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD; +			newtio.c_cflag = B4800;  			break;  		case 2400: -			newtio.c_cflag = B2400 | CS8 | CLOCAL | CREAD; +			newtio.c_cflag = B2400;  			break;  		case 1200: -			newtio.c_cflag = B1200 | CS8 | CLOCAL | CREAD; +			newtio.c_cflag = B1200;  			break;  	} -	newtio.c_cflag |= CRTSCTS;		// CSTOPB - dva stop bity NEE +	newtio.c_cflag |=  CS8 | CLOCAL | CREAD | CRTSCTS;		// CSTOPB - dva stop bity NEE  	printf ("Serial device: %s, communication speed is: %d Bd\n", MODEMDEVICE, baud_rate);  	newtio.c_iflag = 0;  	newtio.c_oflag = 0; @@ -519,15 +684,58 @@ int main(int argc, char** argv, char** env)  	newtio.c_cc[VTIME] = 10;  	tcsetattr(serial_fd, TCSANOW, &newtio);  	tcflush(serial_fd, TCIOFLUSH); +	return 0; +#endif +} + +void CloseUart() { +	if (serial_fd) { +#ifdef __WIN32 +	CloseHandle(serial_fd); +#else +		close (serial_fd); +#endif +	} +} + + + +/************************************************************************/ +/************************************************************************/ +int main(int argc, char** argv, char** env) +{ +#ifndef __WIN32 +	// osetreni breaku ^C v unixech +	saterm.sa_handler = signal_handler_sigterm; +	saterm.sa_flags = 0; +	sigaction (SIGINT, &saterm, NULL); +#endif +	width = GetTerminalWidth(); + +	// nastaveni serioveho portu +	inp_indx = 0; +	if (argc < 2) { +		printf("You must specify the Serial device and file\n"); +		usage(); +		exit(1); +	} +	TestArgs (argc, argv); + +	if (OpenUart() == -1) { +		printf ("Can't open serial port\n"); +		exit (EXIT_FAILURE); +	} + +	#ifndef __WIN32  	spolfd_serial[0].fd = serial_fd;		// nastaveni hlidaneho descriptoru  	spolfd_serial[0].events = POLLIN;		// hlidaji se data na vstupu - +	#endif  	// serial copy activated  	if (is_scp_read) { -		RecvSCP(); +		sercpRecv();  	} else { -		SendSCP(); +		sercpSend();  	} -	close (serial_fd); +	CloseUart();  	return 0;  } | 
