#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <signal.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <sys/socket.h> | |
#include <sys/ioctl.h> | |
#include <net/if.h> | |
#include <net/if_arp.h> | |
#include <netinet/in.h> | |
#include <linux/sockios.h> | |
//#include <cfg_api.h> | |
#include <termios.h> | |
#include <sys/prctl.h> | |
#include <pthread.h> | |
#include <assert.h> | |
#include <sys/select.h> | |
#define UART_DEV "/dev/ttyS0" | |
#define ONE_LEN 4095 | |
typedef unsigned int uint32_t; | |
typedef unsigned char uint8_t; | |
int uart_fd_0 = -1; | |
int uart_fd_1 = -1; | |
int times = 0; | |
int tlen = 0; | |
uint8_t dbuf[2100000]; | |
static const uint8_t crc_table[] = | |
{ | |
0x00,0x31,0x62,0x53,0xc4,0xf5,0xa6,0x97,0xb9,0x88,0xdb,0xea,0x7d,0x4c,0x1f,0x2e, | |
0x43,0x72,0x21,0x10,0x87,0xb6,0xe5,0xd4,0xfa,0xcb,0x98,0xa9,0x3e,0x0f,0x5c,0x6d, | |
0x86,0xb7,0xe4,0xd5,0x42,0x73,0x20,0x11,0x3f,0x0e,0x5d,0x6c,0xfb,0xca,0x99,0xa8, | |
0xc5,0xf4,0xa7,0x96,0x01,0x30,0x63,0x52,0x7c,0x4d,0x1e,0x2f,0xb8,0x89,0xda,0xeb, | |
0x3d,0x0c,0x5f,0x6e,0xf9,0xc8,0x9b,0xaa,0x84,0xb5,0xe6,0xd7,0x40,0x71,0x22,0x13, | |
0x7e,0x4f,0x1c,0x2d,0xba,0x8b,0xd8,0xe9,0xc7,0xf6,0xa5,0x94,0x03,0x32,0x61,0x50, | |
0xbb,0x8a,0xd9,0xe8,0x7f,0x4e,0x1d,0x2c,0x02,0x33,0x60,0x51,0xc6,0xf7,0xa4,0x95, | |
0xf8,0xc9,0x9a,0xab,0x3c,0x0d,0x5e,0x6f,0x41,0x70,0x23,0x12,0x85,0xb4,0xe7,0xd6, | |
0x7a,0x4b,0x18,0x29,0xbe,0x8f,0xdc,0xed,0xc3,0xf2,0xa1,0x90,0x07,0x36,0x65,0x54, | |
0x39,0x08,0x5b,0x6a,0xfd,0xcc,0x9f,0xae,0x80,0xb1,0xe2,0xd3,0x44,0x75,0x26,0x17, | |
0xfc,0xcd,0x9e,0xaf,0x38,0x09,0x5a,0x6b,0x45,0x74,0x27,0x16,0x81,0xb0,0xe3,0xd2, | |
0xbf,0x8e,0xdd,0xec,0x7b,0x4a,0x19,0x28,0x06,0x37,0x64,0x55,0xc2,0xf3,0xa0,0x91, | |
0x47,0x76,0x25,0x14,0x83,0xb2,0xe1,0xd0,0xfe,0xcf,0x9c,0xad,0x3a,0x0b,0x58,0x69, | |
0x04,0x35,0x66,0x57,0xc0,0xf1,0xa2,0x93,0xbd,0x8c,0xdf,0xee,0x79,0x48,0x1b,0x2a, | |
0xc1,0xf0,0xa3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1a,0x2b,0xbc,0x8d,0xde,0xef, | |
0x82,0xb3,0xe0,0xd1,0x46,0x77,0x24,0x15,0x3b,0x0a,0x59,0x68,0xff,0xce,0x9d,0xac | |
}; | |
uint8_t fibo_crc_calc( uint8_t *datain,uint32_t datalen) | |
{ | |
uint8_t *input = (uint8_t*)datain; | |
uint8_t fcs = (uint8_t)0xFF; | |
int32_t i; | |
for (i = 0; i < (int32_t)datalen; i++) | |
fcs = crc_table[fcs ^ (uint8_t)input[i]]; | |
return (uint8_t) (0xFF - fcs); | |
} | |
void int_handle(int signo) | |
{ | |
if(signo == SIGINT) | |
{ | |
printf("recv signal\n"); | |
exit(1); | |
} | |
} | |
int32_t com_Convbaud(uint32_t iBaudrate) | |
{ | |
switch(iBaudrate) | |
{ | |
case 0: | |
return B0; | |
case 50: | |
return B50; | |
case 75: | |
return B75; | |
case 110: | |
return B110; | |
case 134: | |
return B134; | |
case 150: | |
return B150; | |
case 200: | |
return B200; | |
case 300: | |
return B300; | |
case 600: | |
return B600; | |
case 1200: | |
return B1200; | |
case 1800: | |
return B1800; | |
case 2400: | |
return B2400; | |
case 4800: | |
return B4800; | |
case 9600: | |
return B9600; | |
case 19200: | |
return B19200; | |
case 38400: | |
return B38400; | |
case 57600: | |
return B57600; | |
case 115200: | |
return B115200; | |
case 230400: | |
return B230400; | |
case 460800: | |
return B460800; | |
case 500000: | |
return B500000; | |
case 576000: | |
return B576000; | |
case 921600: | |
return B921600; | |
case 1000000: | |
return B1000000; | |
case 1152000: | |
return B1152000; | |
case 1500000: | |
return B1500000; | |
case 2000000: | |
return B2000000; | |
case 2500000: | |
return B2500000; | |
case 3000000: | |
return B3000000; | |
case 3500000: | |
return B3500000; | |
case 4000000: | |
return B4000000; | |
default: | |
return B115200; | |
} | |
} | |
static int com_SetBaud(int32_t iFdCom,int nSpeed) | |
{ | |
int ret = 0; | |
struct termios tOldTermios = {0}; | |
int32_t iBaudrate = 0; | |
bzero(&tOldTermios, sizeof(tOldTermios)); | |
ret = tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions | |
if(ret) | |
{ | |
printf("tcgetattr failed! \n"); | |
} | |
iBaudrate = com_Convbaud(nSpeed); | |
if(iBaudrate == B115200 && nSpeed != 115200){ | |
//got specil baud, not standerd | |
printf("the baud set is not standerd, please call other function to set \n"); | |
return 1; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
cfsetispeed(&tOldTermios, iBaudrate); //填入串口输入端波特率 | |
cfsetospeed(&tOldTermios, iBaudrate); //填入串口输出端波特率 | |
if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效 | |
{ | |
printf("Set vFnSetBaud error. iFd == %d\n", iFdCom); | |
return 1; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
return 0; | |
} | |
static void com_SetnBit(int32_t iFdCom, int nBits) | |
{ | |
struct termios tOldTermios = {0}; | |
bzero(&tOldTermios, sizeof(tOldTermios)); | |
tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions | |
switch( nBits ) | |
{ | |
case 7: | |
tOldTermios.c_cflag |= CS7; | |
break; | |
case 8: | |
default: | |
tOldTermios.c_cflag |= CS8; | |
break; | |
} | |
if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效 | |
{ | |
printf("Set vFnSetnBit error. iFd == %d\n", iFdCom); | |
return; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
} | |
static void com_SetParity(int32_t iFdCom,char nEvent) | |
{ | |
struct termios tOldTermios = {0}; | |
bzero(&tOldTermios, sizeof(tOldTermios)); | |
tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions | |
switch( nEvent ) | |
{ | |
case 'O': //奇校验 | |
tOldTermios.c_cflag |= PARENB; | |
tOldTermios.c_cflag |= PARODD; | |
tOldTermios.c_iflag |= (INPCK | ISTRIP); | |
break; | |
case 'E': //偶校验 | |
tOldTermios.c_iflag |= (INPCK | ISTRIP); | |
tOldTermios.c_cflag |= PARENB; | |
tOldTermios.c_cflag &= ~PARODD; | |
break; | |
case 'N': //无校验 | |
default: | |
tOldTermios.c_cflag &= ~PARENB; | |
break; | |
} | |
if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效 | |
{ | |
printf("Set vFnSetParity error. iFd == %d\n", iFdCom); | |
return; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
} | |
static void com_SetnStop(int32_t iFdCom, int nStop) | |
{ | |
struct termios tOldTermios = {0}; | |
bzero(&tOldTermios, sizeof(tOldTermios)); | |
tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions | |
switch( nStop ) | |
{ | |
case 1: | |
tOldTermios.c_cflag &= ~CSTOPB; | |
break; | |
case 2: | |
tOldTermios.c_cflag |= CSTOPB; | |
break; | |
default: | |
tOldTermios.c_cflag &= ~CSTOPB; | |
break; | |
} | |
if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效 | |
{ | |
printf("Set vFnSetnStop error. iFd == %d\n", iFdCom); | |
return; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
} | |
static void com_SetCtrl(int32_t iFdCom, int nCtrl) | |
{ | |
struct termios tOldTermios = {0}; | |
bzero(&tOldTermios, sizeof(tOldTermios)); | |
tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions | |
switch(nCtrl) | |
{ | |
case 0: | |
{ | |
tOldTermios.c_cflag &= ~CRTSCTS; //no flow control | |
tOldTermios.c_iflag |= IGNBRK | IGNPAR; | |
}break; | |
case 1: | |
{ | |
tOldTermios.c_cflag |= CRTSCTS; //hardware flow control | |
}break; | |
case 2: | |
{ | |
tOldTermios.c_iflag |= IXON | IXOFF | IXANY; //software flow control | |
}break; | |
default: | |
break; | |
} | |
if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效 | |
{ | |
printf("Set vFnSetCtrl error. iFd == %d\n", iFdCom); | |
return; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
//printf("Set vFnSetCtrl end\n"); | |
} | |
static void com_SetTimeOut(int32_t iFdCom, int iTime) | |
{ | |
struct termios tOldTermios = {0}; | |
bzero(&tOldTermios, sizeof(tOldTermios)); | |
tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions | |
tOldTermios.c_cc[VTIME] = iTime; | |
tOldTermios.c_cc[VMIN] = 0; | |
if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效 | |
{ | |
printf("Set TimeOut error. iFd == %d\n", iFdCom); | |
return; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
} | |
static void com_SetIO_Para(int32_t iFdCom) | |
{ | |
struct termios tOldTermios = {0}; | |
bzero(&tOldTermios, sizeof(tOldTermios)); | |
tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions | |
tOldTermios.c_iflag &= ~(ICRNL | IXON); | |
tOldTermios.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ISIG); | |
tOldTermios.c_oflag &= ~OPOST; | |
if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效 | |
{ | |
printf("Set TimeOut error. iFd == %d\n", iFdCom); | |
return; | |
} | |
tcflush(iFdCom, TCIOFLUSH); | |
printf("com_SetIO_Para over.\n"); | |
} | |
static int zUP_SetPort_0(int32_t iFd ,int ctsrts_en, int iBaud, int iDelay) | |
{ | |
com_SetBaud(iFd, iBaud); | |
com_SetnBit(iFd, 8); | |
com_SetParity(iFd, 'N'); | |
//com_SetParity(iFd, 'O'); | |
com_SetnStop(iFd,1); | |
com_SetCtrl(iFd,ctsrts_en); //add flow control | |
com_SetIO_Para(iFd); | |
com_SetTimeOut(iFd,iDelay); //timeout 100ms | |
printf("set serial port done!\n"); | |
return 0; | |
} | |
int block_select_one_time() | |
{ | |
int ret; | |
fd_set rfds; | |
FD_ZERO(&rfds); | |
FD_SET(uart_fd_0,&rfds); | |
ret = select(uart_fd_0+1,&rfds,NULL,NULL,NULL); | |
if(ret == -1) | |
{ | |
printf("select error: -1"); | |
return 0; | |
} | |
else | |
{ | |
return 1; | |
} | |
return 1; | |
} | |
void check_one_time() | |
{ | |
uint8_t crc_board = 0; | |
if((dbuf[0] != 0xA5)||(dbuf[1] != 0x5A)||(dbuf[tlen-2] != 0xD5)||(dbuf[tlen-1] != 0x5D)) | |
{ | |
printf("head or tail error \n"); | |
assert(0); | |
} | |
uint8_t* dbuf2 = NULL; | |
dbuf2 = (uint8_t*)malloc(2100000); | |
if(dbuf2 == NULL) | |
{ | |
printf("malloc failed!\n"); | |
exit(1); | |
} | |
memcpy(dbuf2, dbuf+2, tlen-5); | |
crc_board = fibo_crc_calc(dbuf2,tlen-5); | |
if(crc_board != dbuf[tlen-3]) | |
{ | |
printf("crc error, value is %d\n", crc_board); | |
assert(0); | |
} | |
printf("----------------------crc pass! value :%d----------------------\n", crc_board); | |
if(dbuf2 != NULL) | |
{ | |
free(dbuf2); | |
dbuf2 = NULL; | |
} | |
} | |
int send_one_time() | |
{ | |
int len = 0; | |
len = write(uart_fd_0, ×, 4); | |
if(len <= 0) | |
{ | |
printf("Ack write failed %s\n",strerror(errno)); | |
return 0; | |
} | |
printf("Ack send success index :%d\n", times); | |
return 1; | |
} | |
int read_datas_tty() | |
{ | |
int recv_len = 0; | |
tlen = 0; | |
while(1) | |
{ | |
recv_len = read(uart_fd_0, dbuf+tlen, ONE_LEN); | |
if(recv_len == 0) | |
{ | |
printf("read end! please wait for this packet's handle\n"); | |
break; | |
} | |
else if(recv_len < 0) | |
{ | |
printf("read_datas_tty error %s\n",strerror(errno)); | |
return 0; | |
} | |
else | |
{ | |
tlen += recv_len; | |
} | |
} | |
printf("read last time len :%d total len :%d\n",recv_len, tlen); | |
//printf("0 is %#x, 1 is %#x, -3 is %#x, -2 is %#x, -1 is %#x\n",dbuf[0],dbuf[1],dbuf[tlen-3],dbuf[tlen-2],dbuf[tlen-1]); | |
return 1; | |
} | |
int main(int argc, char** argv) | |
{ | |
int ret0 = 0; | |
int baud = atoi(argv[1]); | |
int delay = atoi(argv[2]); | |
printf("crc main programe start...\n"); | |
signal(SIGINT,int_handle); | |
uart_fd_0 = open("/dev/ttyS0",O_RDWR); | |
if(uart_fd_0 < 0) | |
{ | |
printf("open uart dev failed :%s\n",strerror(errno)); | |
return -1; | |
} | |
zUP_SetPort_0(uart_fd_0, 0, baud, delay); | |
memset(dbuf,0,2100000); | |
while(1) | |
{ | |
ret0 = send_one_time(); | |
if(!ret0) | |
{ | |
break; | |
} | |
if(block_select_one_time()) | |
{ | |
ret0 = read_datas_tty(); | |
if(ret0) | |
{ | |
check_one_time(); | |
times++; | |
} | |
else | |
{ | |
printf("read_datas_tty failed\n"); | |
break; | |
} | |
} | |
} | |
printf("crc main programe end...\n"); | |
close(uart_fd_0); | |
return 1; | |
} | |