首页 > 代码库 > appbox之: linux串口测试程序

appbox之: linux串口测试程序

平台:从网上买的X86平台(baytrail -D (cerelon J1900))

Baytrail平台自带两个串口,基本上就是低端台式机的配置

串口也是同台式机一样


问题:这里将这个X86平台(baytrail cerelon J1900)当成从机设备,

将其接到PC的串口上,一直无输出


解决:串口线两端都是母头,也就是说是直连的,那么这样,baytrail的tx直接与PC的tx相接

所以调了很久都没有任何输出,问题就在于BYT的TX与PC的TX相接,导致PC上看不到BYT设备的输出

所以,调串口设备,一定要注意需要使用交叉线还是直连线,或者说要注意收和发是否对应


另外,上串口测试代码,这也是appbox的一个例程:

#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <dirent.h>
#include <assert.h>
#include <linux/unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <sys/times.h>
#include <sys/time.h>
#include <sys/sysinfo.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>
#include <linux/if_ether.h>
#include <arpa/inet.h>
#include <linux/sockios.h>
#include <sys/mman.h>


/*
平台:从网上买的X86平台(baytrail -D (cerelon J1900))
Baytrail平台自带两个串口,基本上就是低端台式机的配置
串口也是同台式机一样

问题:这里将这个X86平台(baytrail cerelon J1900)当成从机设备,
将其接到PC的串口上,一直无输出

解决:串口线两端都是母头,也就是说是直连的,那么这样,baytrail的tx直接与PC的tx相接
所以调了很久都没有任何输出,问题就在于BYT的TX与PC的TX相接,导致PC上看不到BYT设备的输出

另外,上串口测试代码,这也是appbox的一个例程:
*/
typedef unsigned int            DWORD;
typedef unsigned char           BYTE;

#define LINE_MAX_LENGTH		128
#define NAME_MAX_LENGTH 	32
#define MAX_PATH_LENGTH 	128


/// 串口属性结构
typedef struct COMM_ATTR
 {
	DWORD	baudrate;	///< 实际的波特率值。		
	BYTE	databits;	///< 实际的数据位数。	
	BYTE	parity;		///< 奇偶校验选项,取comm_parity_t类型的枚举值。	
	BYTE	stopbits;	///< 停止位数,取comm_stopbits_t类型的枚举值。	
	BYTE	reserved;	///< 保留	
} COMM_ATTR;

/// 串口停止位类型
enum comm_stopbits_t 
{
	COMM_ONESTOPBIT,	///< 1 stop bit
	COMM_ONE5STOPBITS,	///< 1.5 stop bit
	COMM_TWOSTOPBITS	///< 2 stop bit
};

/// 串口校验位类型
enum comm_parity_t 
{
	COMM_NOPARITY,	///< No parity
	COMM_ODDPARITY,	///< Odd parity
	COMM_EVENPARITY,///< Even parity
	COMM_MARK,		///< 
	COMM_SPACE		///< 
};

typedef enum CommType 
{
	commBus_485 = 0x0001,
	commBus_422 = 0x0002, 
	commBus_232 = 0x0004, 
} CommType;


/// 串口操作中断类型
typedef enum CommPurgeFlags
{
	commPurgeTxAbort = 0x0001,	///< 中止写操作
	commPurgeRxAbort = 0x0002,	///< 中止读操作
	commPurgeTxClear = 0x0004,	///< 清空输出缓冲
	commPurgeRxClear = 0x0008 	///< 清空输入缓冲
} CommPurgeFlags;

/// 串口停止位类型
typedef enum CommStopBit
{
	commOneStopBit = 0,		///< 1 stop bit
	commOne5StopBits,		///< 1.5 stop bit
	commTwoStopBits			//< 2 stop bit
} CommStopBit;

/// 串口校验位类型
typedef enum CommParityType 
{
	commNoParity = 0,	///< No parity
	commOddParity,		///< Odd parity
	commEvenParity,		///< Even parity
	commMarkParity,		///< Mark parity
	commSpaceParity		///< Space parity
} CommParityType;

/// 特殊串口标志
typedef enum CommSpecialFlag
{
	commNormal = 0,
	commRedApple
} CommSpecialFlag;

/// 串口模式
typedef enum CommMode
{
	commFullDuplex = 0,	///< 全双工
	commSemiDuplex,		///< 半双工
} CommMode;


int uartfd = -1;

int FrontboardSetAttr(COMM_ATTR *ParmaAttribute_p)
{
	struct termios Option;
	COMM_ATTR *Attribute_p = ParmaAttribute_p;

	memset(&Option, 0, sizeof(struct termios));
	tcgetattr(uartfd, &Option);

	if(uartfd < 0)
	{
		printf("Index < 0 || UartSetAttributeEx.\n");
		return -1;
	}

	cfmakeraw(&Option);

	switch(Attribute_p->baudrate)
	{
		case 50:
			cfsetispeed(&Option, B50);
			cfsetospeed(&Option, B50);
			break;
		case 75:
			cfsetispeed(&Option, B75);
			cfsetospeed(&Option, B75);
			break;
		case 110:
			cfsetispeed(&Option, B110);
			cfsetospeed(&Option, B110);
			break;
		case 134:
			cfsetispeed(&Option, B134);
			cfsetospeed(&Option, B134);
			break;
		case 150:
			cfsetispeed(&Option, B150);
			cfsetospeed(&Option, B150);
			break;
		case 200:
			cfsetispeed(&Option, B200);
			cfsetospeed(&Option, B200);
			break;
		case 300:
			cfsetispeed(&Option, B300);
			cfsetospeed(&Option, B300);
			break;
		case 600:
			cfsetispeed(&Option, B600);
			cfsetospeed(&Option, B600);
			break;
		case 1200:
			cfsetispeed(&Option, B1200);
			cfsetospeed(&Option, B1200);
			break;
		case 1800:
			cfsetispeed(&Option, B1800);
			cfsetospeed(&Option, B1800);
			break;
		case 2400:
			cfsetispeed(&Option, B2400);
			cfsetospeed(&Option, B2400);
			break;
		case 4800:
			cfsetispeed(&Option, B4800);
			cfsetospeed(&Option, B4800);
			break;
		case 9600:
			cfsetispeed(&Option, B9600);
			cfsetospeed(&Option, B9600);
			break;
		case 19200:
			cfsetispeed(&Option, B19200);
			cfsetospeed(&Option, B19200);
			break;
		case 38400:
			cfsetispeed(&Option, B38400);
			cfsetospeed(&Option, B38400);
			break;
		case 57600:
			cfsetispeed(&Option, B57600);
			cfsetospeed(&Option, B57600);
			break;
		case 115200:
			cfsetispeed(&Option, B115200);
			cfsetospeed(&Option, B115200);
			break;
		default:
			printf("Unsupported baudrate %d\n", Attribute_p->baudrate);
			return -1;
	}

	switch(Attribute_p->parity)
	{
		case commNoParity:				// none			
			Option.c_cflag &= ~PARENB;	// disable parity	
			Option.c_iflag &= ~INPCK;	// disable parity check	
			break;
		case commOddParity:			// odd			
			Option.c_cflag |= PARENB;	// enable parity	
			Option.c_cflag |= PARODD;	// odd			
			Option.c_iflag |= INPCK;	// enable parity check	
			break;
		case commEvenParity:			// even			
			Option.c_cflag |= PARENB;	// enable parity
			Option.c_cflag &= ~PARODD;	// even			
			Option.c_iflag |= INPCK;	// enable parity check	
			break;
		case commMarkParity:
			Option.c_cflag |= PARENB;	/* enable parity	*/
			Option.c_cflag |= PARODD;	/* parity bit is always 1	*/
			break;
		case commSpaceParity:
			Option.c_cflag |= PARENB;	/* enable parity	*/
			break;
		default:
			printf("Unsupported parity %d\n", Attribute_p->parity);
			return -1;
	}

	Option.c_cflag &= ~CSIZE;
	switch (Attribute_p->databits)
	{
		case 5:
			Option.c_cflag |= CS5;
			break;
		case 6:
			Option.c_cflag |= CS6;
			break;
		case 7:
			Option.c_cflag |= CS7;
			break;
		case 8:
			Option.c_cflag |= CS8;
			break;
		default:
			printf("Unsupported data bits %d\n", Attribute_p->databits);
			return -1;
	}
	
	Option.c_cflag &= ~CSTOPB;
	switch (Attribute_p->stopbits)
	{
		case commOneStopBit:
			Option.c_cflag &= ~CSTOPB;
			break;
		case commOne5StopBits:
			break;

		case commTwoStopBits:
			Option.c_cflag |= CSTOPB;
			break;
		default:
			printf("Unsupported stop bits %d\n", Attribute_p->stopbits);
			return -1;
	}

	Option.c_cc[VTIME] = 0;
	Option.c_cc[VMIN]  = 1;

	tcflush(uartfd, TCIOFLUSH);

	if(tcsetattr(uartfd, TCSANOW, &Option) < 0)
	{
		printf("tcsetattr Failed.\n");
		return -1;
	}

	return 0;
}

int FrontboardCreate(void)
{
	char DeviceName[NAME_MAX_LENGTH] = {0};
	int iFbUartIndex;
	COMM_ATTR UartAttribute;

	memset(&UartAttribute, 0, sizeof(UartAttribute));

	if(uartfd > 0)
	{
		return 0;
	}

	iFbUartIndex = 0;
	snprintf(DeviceName, sizeof(DeviceName),"%s%d", "/dev/ttyS", iFbUartIndex);
	printf("DeviceName:%s\n", DeviceName);
	
	uartfd = open(DeviceName, O_RDWR);
	if(uartfd < 0)
	{
		printf("Open %s failed.\n", DeviceName);
		return -1;
	}

	UartAttribute.baudrate = 9600;
	UartAttribute.databits = 8;
	UartAttribute.parity   = commNoParity;
	UartAttribute.stopbits = commOneStopBit;

	if(FrontboardSetAttr(&UartAttribute) < 0)
	{
		printf("UartSetAttributeEx Failed. \n");
		return -1;
	}

	return 0;
}

int FrontboardDestory(void)
{
	if(uartfd > 0)
	{
		close(uartfd);
		uartfd = -1;
	}

	return 0;
}

int FrontboardRead(void *pData, DWORD nBytes)
{
	int ReadLength = 0;
	int ReadPosition = 0;

	if(NULL == pData || nBytes < 0)
	{
		printf("Invalid Params, NULL == pData or nBytes < 0.\n");
		return -1;
	}

	memset(pData, 0, nBytes);

	while(0 != nBytes)
	{
		ReadLength = read(uartfd, pData + ReadPosition, nBytes);

		if(ReadLength < 0)
		{
			printf("read Failed, ReadLength < 0.\n");
			return -1;
		}

		ReadPosition += ReadLength;
		nBytes -= ReadLength;
	}

	return ReadPosition;
}

int FrontboardWrite(void *pData, DWORD nBytes)
{
	int WriteLength 	= 0;
	int WritePosition 	= 0;

	if(NULL == pData || nBytes < 0)
	{
		printf("Invalid Params, NULL == pData || nBytes < 0.\n");
		return -1;
	}

	while(0 != nBytes)
	{
		WriteLength = write(uartfd, pData + WritePosition, nBytes);
		if(WriteLength < 0)
		{
			printf("write failed, nBytes:%d, WriteLength:%d\n", nBytes, WriteLength);
			return -1;
		}

		WritePosition += WriteLength;
		nBytes -= WriteLength;
	}

	return WritePosition;
}

int main(int argc, char *argv[])
{
	unsigned char pData[8] = {0};

	pData[0] = 'a';
	pData[1] = 'b';
	pData[2] = 'c';
	pData[3] = 'd';
	pData[4] = '\n';

	FrontboardCreate();

	while(1)
	{
		printf("frontboardwrite:\n");
		FrontboardWrite((void*)pData, 8);
		sleep(1);
	}

	return 0;
}



appbox之: linux串口测试程序