</pre><pre name="code" class="cpp">/**
*@Title:利用多线程同步通信机制实现串口通信
*@Introduce:主要完成根据特定的通信协议实现串口与PC上特定串口
* 通信软件的通信。测试版,只是完成主要框架,没有完全将协议的
* 所有通信方式方法做完。
* 其中包含的测试功能有:监听主机(PC上的软件)发送的特定请求,
* 能够识别类型,并解析包含里面的信息,并且自动回复,所写的根
* 据协议要求的固定消息结构体。
* 实现原理:多线程,同步,通信。
* 其中一个线程专门读取串口中从主机传递的信号,并通过识别出来
* 的长度(length),将一个完整的包截取下来,利用识别出来的类
* 型(type)将包以字符串缓存形式发往特定的处理线程。
* 特定的线程按操作分,有两类,一类主动发出请求信号等待主机回
* 应;另一类,等待主机发送请求,然后根据指令回应相关信息
* 说明:在这里,因为只是为了做功能测试,所以所有的解析并根据
* 相应信息内容做处理的操作统一简化为将内容打印出来显示。
*@Attention:主要难点代码中也有注释,这边稍微记录我的错误提醒
* 在这个同步通信机制中,不同线程通过一个全局的指针list_head
* m_req_list作为机制,所有需要的线程中传递的结构体都挂在它下
* 面,然后传递信息的结构体也有通用格式GeneralReqT,根据里面
* type参量确定不同类型,buffer存储需要传递的字符串信息。
*@Explain:包含的文件名有:dev_com_main.c(主函数所在文件)
* dev_com_main.h(主函数的头文件)
* list.h(特殊的list_head结构体的说明和相关函数宏的说明文件)
* crc16.c,crc16.h(CRC16校验码生成的函数体文件和头文件)
* linux下交叉编译试例:
* 确保上述文件都放在当前文件夹下,输入:
* #gcc -o dev dev_com_main.c crc16.c -I ./ -lpthread
* 交叉编译,更换gcc便好。
*@Author:wanney
*@Date:2014-10-25
*@e-Mail:wanney216@gmail.com
*@长江不择细流,泰山不辞抔土。
*/
#include "dev_com_main.h"
#include <pthread.h>
#include <malloc.h>
#define SHOWCHAR 1
#define SHOWHEX 0
#define HEADLOGO 0xaa55
//对于静态分配的互斥量, 可以把它设置为PTHREAD_MUTEX_INITIALIZER,
//或者调用pthread_mutex_init
static pthread_mutex_t m_mutex = PTHREAD_MUTEX_INITIALIZER;
//形成一个闭环,是当前结构体的前节点和后节点都指向本身。
static struct list_head m_req_list = {&m_req_list, &m_req_list};
//串口打开的初始化
//参数:串口设备的路径名 dev,设置整型的波特率(注意格式匹配)
//设备路径名出错会报错,波特率输出默认为:9600
//其他参数设默认值:数据位:8位,校验位:无,停止位:1位
int uart_open (char *dev, int baud)
{
struct termios tio;
int fd;
int baud_flags;
fd = open(dev, O_RDWR);
if(fd == -1) {
// fprintf(stdout, "open %s error!\n", dev);
return -1;
}
if(tcgetattr(fd, &tio) < 0) {
// fprintf(stdout, "tcgetattr error!\n");
close(fd);
return -1;
}
switch (baud) {
case 115200:
baud_flags = B115200;
break;
case 57600:
baud_flags = B57600;
break;
case 38400:
baud_flags = B38400;
break;
case 19200:
baud_flags = B19200;
break;
case 9600:
baud_flags = B9600;
break;
case 2400:
baud_flags = B2400;
break;
case 4800:
baud_flags = B4800;
break;
default:
baud_flags = B9600;
break;
}
fcntl(fd, F_SETFL,O_NONBLOCK);
tio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG | ECHOE);
tio.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON | BRKINT);
tio.c_iflag &= ~(CSIZE | PARENB | CSTOPB);
tio.c_oflag &= ~(OPOST);
tio.c_cflag = CS8 | baud_flags | CLOCAL | CREAD;
tio.c_cc[VMIN] = 0;
tio.c_cc[VTIME] = 0;
tcflush(fd, TCIFLUSH);
if(tcsetattr(fd, TCSAFLUSH, &tio) < 0) {
// fprintf(stdout,"tcsetattr error!\n");
close(fd);
return -1;
}
printf("open uart:%s, baud:%d", dev, baud);
return fd;
}
//初始化:从机参数查询消息的应答消息
void initAnsCheckInfoC(unsigned char * buf,pAnsCheckInfoC p_ans_check_info){
unsigned char buf_[26] ;
WORD crc16;
int i;
memset(buf_,0x00,sizeof(buf_));
p_ans_check_info->infohead.logo = HEADLOGO;
p_ans_check_info->infohead.type = 0x7006;
p_ans_check_info->infohead.length = 0x0e;
p_ans_check_i