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

📄 stest.cpp

📁 linux下的串口测试程序
💻 CPP
字号:
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
//#include <es.h>
#include <linespack.h>
#include "scomm.h"
#include <sys/types.h>
#include <sys/select.h>
#include "main.h"

static unsigned char buf[512];
static int rn = 3;

#define MODEM
#ifdef  MODEM
#include <sys/ioctl.h>
/*
 * These are the definitions for the Modem Control Register
 */
#define UART_MCR_LOOP	0x10	/* Enable loopback test mode */
#define UART_MCR_OUT2	0x08	/* Out2 complement */
#define UART_MCR_OUT1	0x04	/* Out1 complement */
#define UART_MCR_RTS	0x02	/* RTS complement */
#define UART_MCR_DTR	0x01	/* DTR complement */

static unsigned int dtr_flag = TIOCM_DTR;

static int get_dtr()
{
	int new_flag;
	ioctl(s.fd(), TIOCMGET, &new_flag);
	return new_flag;
}

static void set_dtr(bool val)
{
	ioctl(s.fd(), val?TIOCMBIS:TIOCMBIC, &dtr_flag);
}
#endif

static unsigned char hexc2d(const char *hexc)
{
	unsigned char x = 0;
	char c = *hexc;
	c>='0'&&c<='9'?x=(c-'0')*16:0;
	c>='a'&&c<='f'?x=(c-'a'+10)*16:0;
	c>='A'&&c<='F'?x=(c-'A'+10)*16:0;
	c = *(hexc+1);
	c>='0'&&c<='9'?x+=(c-'0'):0;
	c>='a'&&c<='f'?x+=(c-'a'+10):0;
	c>='A'&&c<='F'?x+=(c-'A'+10):0;

	return x;
}

static void write_scomm(unsigned char *buf, int len)
{
	int i=0;
	unsigned char sbuf[256];
	uchar *pdata;
	if(buf[0]=='0' && buf[1]=='x'){
		pdata = sbuf;
		unsigned char *p = buf+2;
		for(;i<(len-1)/3;i++)
			sbuf[i] = hexc2d((const char*)p+3*i);
	}
	else{
		pdata = buf;
		if(rn & 1){
			buf[len+i++] = '\r';
		}
		if(rn & 2){
			buf[len+i++] = '\n';
		}
		i+=len;
	}
	
	if(i>0){
#ifdef MODEM
		set_dtr(false);
#endif
		s.write(pdata, i);
#ifdef MODEM
		set_dtr(true);
#endif
	}
}

static int run(bool strmode)
{
	fd_set set;
	for( ; ; ){
		FD_ZERO(&set);
		FD_SET(0, &set);
		FD_SET(s.fd(), &set);
		
		timeval tv;
		tv.tv_sec  = 0;
		tv.tv_usec = 100*1000;

		int retcode;
		if((retcode=select(s.fd()+1, &set, NULL, NULL, &tv)) < 0){  // extern abort
			if(errno==EINTR){
				fprintf(stderr, "sub process EINTR\n");
			}else{
				fprintf(stderr, "sub select error\n");
			}
			return(-1);
		}

		if(retcode == 0){   // time over
			continue;
		}
		if(FD_ISSET(0, &set)){
			static lines_pack rbuf;
			int n = read(0, buf, sizeof(buf));
			if(n<=0){
				fprintf(stderr, "stdio closed\n");
				return 0;
			}
			rbuf.push(buf, n);
			char *pstr = NULL;
			while(rbuf.pop(&pstr)){
				if(strcmp(pstr, "exit")==0){
					fprintf(stderr, "==exit\n");
					return 0;
				}
				else if(strcmp(pstr, "sdtr")==0){
					set_dtr(true);
				}
				else if(strcmp(pstr, "cdtr")==0){
					set_dtr(false);
				}
				else if(strcmp(pstr, "gdtr")==0){
					printf("dtr=0x%.8x\n", get_dtr());
				}
				else if(strncmp(pstr, "sleep ", 6)==0){
					int ms = atoi(pstr+6);
					fprintf(stderr, "==sleep %d(s)\n", ms);
					sleep(ms);
				}
				else{
					write_scomm((uchar*)pstr, strlen(pstr));
				}
			}
		}
		if(FD_ISSET(s.fd(), &set)){
			static lines_pack rbuf;
			int n = s.read(buf, sizeof(buf));
			if(n<=0){
				fprintf(stderr, "scom closed\n");
				return 0;
			}
			if(strmode){
				rbuf.push(buf, n);
				char *pstr = NULL;

				while(rbuf.pop(&pstr)){
					printf("%s\n", pstr);
					fflush(stdout);
				}
			}
			else{
				buf[n] = 0;
				for(int i=0;i<n;i++){
					fprintf(stdout, "%.2x ", buf[i]);
				}
				fprintf(stdout, "\n");
//				fprintf(stderr, (const char *)buf);
			}
		}
	}
	return 0;
}
//#stest -d /dev/ttyS0 -b 57600 -s
static int usage(const char *program)
{
	printf("Usage:\n  %s [-d <device>] [-b <baud>] [-s] [-x] [-r] [-h]\n", program);
	printf("\t-d 串口设备名 默认/dev/ttyS0\n");
	printf("\t-b 波特率 默认57600\n");
	printf("\t-s 字符串模式 <默认模式>\n");
	printf("\t-x 十六进制模式\n");
	printf("\t-r 字符串模式下,在一行数据末尾发送分隔符\n");
	printf("\t   有效的分隔符为[r,n,rn],取其它值为无分隔符.默认为rn\n");
	printf("\t-h 显示本帮助\n\n");
	return 1;
}

int main_stest(int argc, char **argv)
{
	char szdev[16]  = "/dev/ttyS0";
	int  baud = 57600;
	bool strmode = true;
	static const char *optString = "d:b:sxhr:";

	int opt = getopt( argc, argv, optString );
//	if(opt==-1){
//		return usage(argv[0]); 
//	}
	while( opt != -1 ) {
		switch( opt ) {
			case 'd':
				if(*optarg != '/')
					sprintf(szdev, "%s%d", "/dev/ttyS", atoi(optarg));
				else
					strncpy(szdev,  optarg, sizeof(szdev)-1);
				break;
			case 'b':
				baud = atoi(optarg);
				break;
			case 's':
				strmode = true;
				break;
			case 'x':
				strmode = false;
				break;
			case 'r':
				if(strcmp(optarg, "r")==0)
					rn = 1;
				else if(strcmp(optarg, "n")==0)
					rn = 2;
				else if(strcmp(optarg, "rn")==0)
					rn = 3;
				else
					rn = 0;
				break;
			case 'h':
			default:
				return usage(argv[0]); 
				break;
		}
		opt = getopt( argc, argv, optString );
	}

	int result = s.open(szdev);
	if(result != 0){
		fprintf(stderr, "open scomm fail! device=%s\n", szdev);
		return -1;
	}

	s.set_baud(baud);

	run(strmode);
	
	s.close();
	fprintf(stderr, "scomm closed\n");
	return 0;
}

// vim: ts=4 sw=4 cindent

⌨️ 快捷键说明

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