操作系统:ubuntu10.04
前言:
在稍微大点的项目中,且是并发的,基本上都要使用线程来接收数据。
一,源码
(1) 头文件
-
/*
-
* upper,上位机
-
* {
-
*/
-
-
/* 串口的初始化 */
-
extern int32_t com_init_upper(void *param);
-
-
/* 串口的发送 */
-
extern int32_t com_send_upper(uint8_t *send_buffer,int32_t buffer_len);
-
-
/* 串口参数设置
-
* 波特率,停止位,校验位,流控制,异步同步等
-
*/
-
extern int32_t com_set_upper(void *param);
-
-
/* 串口设置参数生效 */
-
extern int32_t com_set_effect_upper(void *param);
-
-
/* 串口关闭*/
-
extern int32_t com_close_upper(void *param);
-
-
/* 串口接收线程关闭 */
-
extern int32_t com_recv_thread_close(void *param);
-
/*
-
* upper,上位机
-
* }
-
*/
(2) *.c 文件
-
/*
-
* upper,上位机
-
* {
-
*/
-
-
#define UPPER_DEVICE_COM "/dev/ttySAC3"
-
/* 串口数据接收线程(是上位机(pc)与 Real210开发板通信) */
-
static pthread_t com_recv_threadid = 0;
-
-
static int32_t upper_device_comfd = 0; /* 与上位机通信的串口的描述符(PC机) */
-
-
-
/* 串口的基本配置 */
-
static int32_t _com_set_upper()
-
{
-
int32_t ret = 0;
-
-
// ret = __com_set(upper_device_comfd,B115200);
-
int32_t fd = upper_device_comfd;
-
struct termios opt;
-
// struct timeval start;
-
-
tcgetattr(fd, &opt);
-
cfsetispeed(&opt, B115200);
-
cfsetospeed(&opt, B115200);
-
// cfsetispeed(&opt, baud_rate);
-
// cfsetospeed(&opt, baud_rate);
-
-
// 8n1
-
opt.c_cflag &= ~CSIZE;
-
opt.c_cflag &= ~CSTOPB;
-
opt.c_cflag &= ~PARENB; // 无奇偶校验
-
opt.c_cflag |= CS8;
-
-
opt.c_cflag &= ~CRTSCTS; // 没有使用硬件流控制
-
-
// opt.c_cflag &= ~INPCK;
-
opt.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode
-
-
// opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 原始数据
-
opt.c_lflag |= (ICANON | ECHO | ECHOE); // 经典数据
-
-
opt.c_oflag &= ~OPOST;
-
opt.c_oflag &= ~(ONLCR | OCRNL); // 添加的
-
-
opt.c_iflag &= ~(ICRNL | INLCR);
-
opt.c_iflag &= ~(IXON | IXOFF | IXANY); // 没有软件流控制
-
-
tcflush(fd, TCIOFLUSH);
-
-
opt.c_cc[VTIME] = 1; // 以 十分之一秒(1/10 s) 为单位
-
opt.c_cc[VMIN] = 0;
-
-
-
-
if(tcsetattr(fd, TCSANOW, &opt) != 0 )
-
{
-
perror("tcsetattr error");
-
return -COM_CONFIG_ERROR;
-
}
-
-
return OPER_OK;
-
}
-
-
-
-
void* com_recv_upper(void *param)
-
{
-
uint8_t recv_buffer[COM_BUFFER_SIZE] = {0};
-
int32_t len = 0;
-
-
while(1)
-
{
-
if(upper_device_comfd > 0)
-
{
-
memset(recv_buffer,0,sizeof(recv_buffer));
-
len = read(upper_device_comfd,recv_buffer,sizeof(recv_buffer));
-
-
if(len > 0) printf("com recv thread : %s\n",recv_buffer);
-
}
-
else // 串口异常或是关闭了
-
{
-
break;
-
}
-
}
-
-
pthread_exit(0);
-
//用pthread_exit()来调用线程的返回值,用来退出线程,但是退出线程所占用的资源不会随着线程的终止而得到释放
-
-
return NULL;
-
}
-
-
-
-
-
/* 串口的初始化 */
-
int32_t com_init_upper(void *param)
-
{
-
int32_t ret = 0;
-
-
;
-
-
upper_device_comfd = open(UPPER_DEVICE_COM,O_RDWR | O_NOCTTY | O_NDELAY);
-
if(upper_device_comfd< 0)
-
{
-
ret = -COM_OPEN_ERROR;
-
}
-
else
-
{
-
if((ret = _com_set_upper()) == OPER_OK)
-
{
-
if((ret = pthread_create(&com_recv_threadid,NULL,com_recv_upper,NULL))!= 0)
-
ret = -THREAD_CREATE_ERROR;
-
}
-
}
-
-
-
return ret;
-
}
-
-
-
-
/* 串口的发送
-
* 返回值: 正常返回发送的字节数,0表示没有数据需要发送。
-
* -1表示异常,也可通过errno获取异常码.
-
*/
-
int32_t com_send_upper(uint8_t *send_buffer,int32_t buffer_len)
-
{
-
int32_t ret = 0;
-
-
// 疑问1:发送数据的长度是否需要判断有效值,有效值是多少??
-
-
ret = write(upper_device_comfd, send_buffer, buffer_len);
-
-
return ret;
-
}
-
-
-
/* 串口参数设置
-
* 波特率,停止位,校验位,流控制,异步同步等
-
*/
-
int32_t com_set_upper(void *param)
-
{
-
int32_t ret = 0;
-
-
-
return ret;
-
}
-
-
-
-
/* 串口设置参数生效 */
-
int32_t com_set_effect_upper(void *param)
-
{
-
int32_t ret = 0;
-
-
-
return ret;
-
}
-
-
-
-
/* 串口关闭*/
-
int32_t com_close_upper(void *param)
-
{
-
int32_t ret = 0;
-
-
if(upper_device_comfd > 0 )
-
{
-
close(upper_device_comfd);
-
upper_device_comfd = 0;
-
}
-
-
return ret;
-
}
-
-
-
-
-
/* 串口接收线程关闭 */
-
int32_t com_recv_thread_close(void *param)
-
{
-
int32_t ret = 0;
-
-
pthread_join(com_recv_threadid,NULL);
-
-
return ret;
-
}
-
-
/*
-
* upper,上位机
-
* }
-
*/
(3) 测试
-
void test_com()
-
{
-
printf("hello\n");
-
-
com_init_upper(NULL);
-
while(1);
-
}
二,操作结果
(1) pc上输入终端,在 SecureCRT 5.2 中 按下 Enter 键,会显示为 ^M。
(2) pc上显示终端。
阅读(3324) | 评论(0) | 转发(4) |