- 论坛徽章:
- 0
|
大家好,这几天做一个linux-2.6.9环境下通信的小项目。硬件是R8610 x86结构,就是一个嵌入式硬件平台。
本来感觉很简单,其实就是串口和网口的通信。从socket接受数据,然后传送给串口,或者从串口接受数据送给socket。只是这里的串口试用的是pl2303 usb转串口。整个代码的大体框架是select + read ,read到数据就write到另外的口。我是这样测试的,r8610有一个网口,一个pl2303usb转的串口,这两个口就是我们要通信的接口。我把这个串口通过串口线接到pc上的com1.这样,测试的时候出现问题啦,!!当然这个问题也可以通过定义自己的通信协议来解决。但是如果大家有意能解决的话,不是很好吗,或者谁以前遇到过一样的问题,大家可以共享一下。反正目前我还没有解决掉,惭愧啊。
retval = select(max_fd, &fds, NULL, NULL,&tv_value);
if(retval > 0)
{
if(FD_ISSET(real_socket_fd, &fds))//socket readable
{
len = commu_read(real_socket_fd, recv_socket_buf, 100);
if(len > 0)//read success from socket
{
socket_err_count = 0;
recv_socket_buf[len] = '\0';
printf("got data from socket is %s\n", recv_socket_buf);
//tcdrain(serial_fd);
ret = commu_write(serial_fd, recv_socket_buf, len);//send the received data from socket to serial port
if(ret > 0)//send to serial success
{
printf("write to serial success, num : %d\n", ret);
serial_err_count = 0;
}
。。。。。。。
}
commu_read和commu_write是read和write的封装函数,
但是从网络收到数据,然后发送到串口的时候,第一次pc上的com1口经常没有收不到数据。比如,从网络收到串“abcde”,通过看打印出的信息,commu_read确实从socket_fd上读到数据。长度是5,并且commu_write的返回值也确实是5,从应用层来看,数据读和写都没有错误。但是pc上的com1口确实没有收到数据。不管第一次收没收到数据,接下来的接受和发送都正常。
上面说的第一次是这个意思:我的代码是服务器端,pc是客户端,“第一次发送数据”指客户端连接到服务器上以后第一次发送的数据,这里的数据不是一个字节。
在我的测试当中,有下面几个重要点:
1 第一次pc没有接收到数据,第一次以后能接收到数据,说明硬件没有问题,我怕用示波器查看com口的引脚,第一次确实没有发出来,第一次以后确实发出来了。
2 我第一次发送“abcde”,没有成功,接下来继续发送,把内容改成“123456789”,pc的com1口直接显示“123456789”,说明驱动缓冲区中把“abcde”刷了,没有驻留。
3 在pl2303驱动中的pl2303_write函数中:
static int pl2303_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
{
int result;
printk("LF:%s - port %d, %d bytes\n", __FUNCTION__, port->number, count);//add by lifeng on 2012-4-23
if (!count)
return count;
if (port->write_urb->status == -EINPROGRESS)
return 0;
printk("LF:count = %d, port->bulk_out_size = %d,from_user = %d\n", count, port->bulk_out_size, from_user);//add by lifeng on 2012-4-23
count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
if (from_user)
{
if (copy_from_user (port->write_urb->transfer_buffer, buf, count))
return -EFAULT;
}
else
{
memcpy (port->write_urb->transfer_buffer, buf, count);
}
printk("LF: write buf :%s\n", port->write_urb->transfer_buffer);
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer);
port->write_urb->transfer_buffer_length = count;
port->write_urb->dev = port->serial->dev;
result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
if (result)
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
else
result = count;
printk("LF:result = %d\n", result);//add by lifeng on 2012-4-23
return result;
}
打印write_urb->transfer_buffer和write_urb->transfer_buffer_length分别是“abcde”和5,也是正确的,usb_submit_urb函数返回值是0,也是正确的。也正常的调用了write_urb的写回调函数。
那么貌似问题出在linux这个版本usbcore的写队列对第一个数据的处理上,对usbcore这一块目前还不是很了解,正在研究中。。。
谁在这方面有过类似经验,可以提供一些帮助,可以尽快解决这问题,
另外老板着急要货,目前已经通过定义通信协议把这个问题绕过,但是我还是想弄的明白点,又怕新任务安排下来,把这个问题忘了,所以在这里留下上面内容,
|
|