LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   linux serial com problem (https://www.linuxquestions.org/questions/programming-9/linux-serial-com-problem-744285/)

solo0805 07-31-2009 11:22 PM

linux serial com problem
 
hello

before i question, my english skill is so awful.

if you are angry at me. i don't intend it.

please forgive me. writing english is too hard to me.

//

i try to make program that use serial port.

two computer communicate between uart.

one is window.
the other is linux.

linux->window is perfect.

but window->linux is wrong.

if i try send data window->linux, sometimes stream is wrong.

but ascii stream is ok.

, i want send binary stream. example(0x00 0x01 0x00 0x02)

but if i try send stream that have '0x00'. linux receiver stream is different.


it just happen in not ascii mode, and 0x00


then i check the pattern.

i send some binary.

2byte

00 01 -> 00 c0
00 02 -> 00 e0
00 03 -> 00 e0
00 04 -> 00 f0
00 05 -> 00 c1
00 06 -> 00 f0
00 07 -> 00 f0
00 08 -> 00 f8
00 09 -> 00 c2
00 10 -> 00 fc

i am so sad.

i googling much, but i can't solve this problem

i check the raw input, non-canonical input ... adjust all setting in web.

but it didn't working.



i guess it is not binary mode.


please help me.
i have to send/receive binary stream.

wje_lq 08-01-2009 03:31 AM

Quote:

Originally Posted by solo0805 (Post 3627319)
hello

before i question, my english skill is so awful.

if you are angry at me. i don't intend it.

please forgive me. writing english is too hard to me.

//

i try to make program that use serial port.

two computer communicate between uart.

one is window.
the other is linux.

linux->window is perfect.

but window->linux is wrong.

if i try send data window->linux, sometimes stream is wrong.

but ascii stream is ok.

, i want send binary stream. example(0x00 0x01 0x00 0x02)

but if i try send stream that have '0x00'. linux receiver stream is different.


it just happen in not ascii mode, and 0x00


then i check the pattern.

i send some binary.

2byte

00 01 -> 00 c0
00 02 -> 00 e0
00 03 -> 00 e0
00 04 -> 00 f0
00 05 -> 00 c1
00 06 -> 00 f0
00 07 -> 00 f0
00 08 -> 00 f8
00 09 -> 00 c2
00 10 -> 00 fc

i am so sad.

i googling much, but i can't solve this problem

i check the raw input, non-canonical input ... adjust all setting in web.

but it didn't working.



i guess it is not binary mode.


please help me.
i have to send/receive binary stream.

Your English is quite adequate for this problem; don't worry about that.

I have several thoughts.
  1. When you say "adjust all setting in web", what do you mean? (Don't worry about your English skills; we'll ask questions if we don't understand.)
  2. Have you correctly specified the Baud rate, the parity, and so forth on both the sending and receiving side?
  3. Could you please post both the sending and receiving program code? (Preferably, programs which are large enough to show us the problem, but not much larger than that.)

solo0805 08-01-2009 03:51 AM

Quote:

Originally Posted by wje_lq (Post 3627421)
Your English is quite adequate for this problem; don't worry about that.

I have several thoughts.
  1. When you say "adjust all setting in web", what do you mean? (Don't worry about your English skills; we'll ask questions if we don't understand.)
  2. Have you correctly specified the Baud rate, the parity, and so forth on both the sending and receiving side?
  3. Could you please post both the sending and receiving program code? (Preferably, programs which are large enough to show us the problem, but not much larger than that.)


i use some keyword to find solution. (linux serial raw data, binary mode, raw input data, binary input data).

then i try adjust that.

below source is last version.

i read document about stty flag.
and first i setting, but it didn't work.

next, i modify my code, program don't set tty option.
and i use 'stty' command, turn on raw , but it didn't work.
and i use other option that i think useless.


second. i check the baudrate using 'stty -F /dev/ttyAM1'
and also i setting baudrate in my program(ospeed and ispeed(header tell me this is not uses))

Quote:


#define UARTTARGETDEVICE "/dev/ttyAM1"

int uartFd;
FILE* uFile;

void uartsignalHandler(int status);

bool InitializeUart()
{
uartFd = open(UARTTARGETDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK );
if (uartFd < 0)
{
printf("UART Open Error!");
return false;
}
struct sigaction saio;
saio.sa_handler = uartsignalHandler;
sigemptyset(&saio.sa_mask);
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO, &saio, NULL);

fcntl(uartFd, F_SETOWN, getpid());
fcntl(uartFd, F_SETFL, FASYNC);

struct termios newtio;
tcgetattr(uartFd, &newtio);
memset(&newtio, 0, sizeof(termios));

newtio.c_cflag = B115200 | CS8 | CREAD | CLOCAL;
newtio.c_iflag = 0 ;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
cfmakeraw(&newtio);

tcsetattr(uartFd, TCSANOW, &newtio);

tcflush(uartFd, TCIFLUSH);
tcflush(uartFd, TCOFLUSH);

return true;
}

int uartRet;
unsigned char uartBuffer[128];

void uartsignalHandler(int status)
{
uartRet = read(uartFd, uartBuffer, 128);

for (int i = 0; i<uartRet; i++)
{
rf->GetByte(uartBuffer[i]);
printf("%#x ", uartBuffer[i]);
}

printf("\r\n");
fflush(stdout);
}

void uartWriteStream(unsigned char* stream, int length)
{
write(uartFd, stream, length);
}


i use xbee module,

linux-xbee - xbee-window

i think maybe xbee's problem.

but i check that using echo mode and input buffer.

i think it is terminal setting's wrong.


because if window send binary stream(0x00 0x01 0x00 0x01)

linux receive binary stream.

somtimes 0x00 0x01 0x00 0x01.
but sometimes like 0x00 0x01 0xe0.

wrong character and missing byte

i experiment too much.

then, ascii is perfectly trans and receive.

and i guess(almost 20 experiment) binary stream that not include 0x00,
is perfectly trans and receive.

ex)0x01 0x02 0x03 0x04 -> this is ok.


but i include 0x00, stream is not correct.

wje_lq 08-01-2009 11:30 AM

There's nothing glaringly wrong in your code, but I have a couple of thoughts.
  1. You did right to do a tcgetattr(), change the attributes, and then do a tcsetattr(). But the memset() just after the tcgetattr() throws away everything you got in the tcgetattr(). You should probably get rid of the memset(). Then, after you've recompiled, it can't hurt to reboot just once. You may have thrown away some undocumented bits or bits which shouldn't be changed. I'm not sure on that, but you do need to get rid of the memset() and it can't hurt to reboot.
  2. I'm not sure that this is a problem, but rather than setting B115200 directly as you do, use cfsetspeed(), after any other changes you make to c_cflag.
  3. Your data suggests a mismatch between the sending and receiving sides. Just recheck all your parameters to make sure that the Windows sender and the code you've shown us have matching speed, parity (or lack there of, actually), and number of stop bits.
  4. If all else fails and you can find another Linux machine, try sending data from a Linux machine to a Linux machine. That may help you find the problem.
Good luck! Sorry I couldn't be of more help.

solo0805 08-01-2009 08:56 PM

I really thank your help.

i see your reply, then i try that and i do some test.

first, i solve this problem partly.


i change my baudrate 115200->57600,

then it works..

i did not change another options..

my mcu's power is 200mhz.

i think linux application signer handler is not stop interrupt. isn't it?

in my source, getdata part is maybe too long. but i think signal handler is just some kind of function.

i think it didn't effect kerner driver.


i think my cpu power is enough, i see 115200 in 60mhz.

oh.. i can just pass this problem now, but it make me curios.


-----

i modify the source like

signalhandler{
uartread = true;
}

main()
{
if (uartread)
read
}

but it work wrong in 115200.

theNbomr 08-03-2009 12:29 PM

I would check the cabling. Errors that occur only at high bit rates can be a result of capacitance in the cables (too long), incorrect connections such as poor solder joints or weak crimps, incorrect cable type, etc. 115200 bps is at the upper end of the RS-232 speed spectrum, due to slew rate limiting of the output drivers. Any substandard cabling may result in the errors you are seeing. The worst-case scenario for these errors would be alternating 1's and 0's, such as ASCII character 'U'.
If this is the cause of your errors, you should be able to duplicate the problem using a known-good serial communications tool, such as minicom or C-kermit. In any case, these kinds of tools are very useful for developing two-way communications programs, as a way of generating known-good data, or having a known-good receiver.
Useful information can be read at
Serial HOWTO
Serial Programming HOWTO
Serial Programming Guide for POSIX Operating Systems

--- rod.

salasi 08-03-2009 02:17 PM

While theNbomr is correct about cable capacitances being a possible source of the problem, if this is a short cable run, I suspect flow control and buffer overruns are more likely, in this case.

First question; is slowing the data rate acceptable to you?

Quote:

i guess it is not binary mode.
Bear in mind that if you are using software flow control, some of your data will be the same as the XON/XOFF characters, so this can't work.

I wasn't all that sure about your table
Code:

2byte

00 01 -> 00 c0
00 02 -> 00 e0
00 03 -> 00 e0
00 04 -> 00 f0
00 05 -> 00 c1
00 06 -> 00 f0
00 07 -> 00 f0
00 08 -> 00 f8
00 09 -> 00 c2
00 10 -> 00 fc

at first it looks like there is just a 1 bit error, but later it looks like several bits; are you sure that you aren't loosing data (if you receive less data than you send, you'll end up comparing different received data than the transmitted data and that will confuse things, depending on the sent data pattern).

wje_lq 08-03-2009 06:39 PM

Quote:

Originally Posted by salasi (Post 3629972)
if you are using software flow control

From reading his code, he's not using software flow control.

wje_lq 08-03-2009 06:43 PM

Quote:

Originally Posted by solo0805 (Post 3628104)
i change my baudrate 115200->57600,

then it works..

Quote:

Originally Posted by solo0805 (Post 3628104)
oh.. i can just pass this problem now, but it make me curios.

So he's done here. It works by dropping the baud rate. It's not clear whether the rates on the sending and receiving side mismatched, and he just fixed that, or whether they matched before and he dropped both sides. Either way, he's solved his problem.

solo0805 08-03-2009 08:22 PM

oh, many reply is appeared.

i can't reply quickly because i live in korea.

maybe when i sleep, you wake up. when i wake up, you sleep..


thank for every reply.

Quote:

I would check the cabling. Errors that occur only at high bit rates can be a result of capacitance in the cables (too long), incorrect connections such as poor solder joints or weak crimps, incorrect cable type, etc. 115200 bps is at the upper end of the RS-232 speed spectrum, due to slew rate limiting of the output drivers. Any substandard cabling may result in the errors you are seeing. The worst-case scenario for these errors would be alternating 1's and 0's, such as ASCII character 'U'.
i check my cable, my cable's length is 60cm~70cm.

i found rs-232's wire length document.

it say
Baud Rate Max Cable Length
1200 400m
4800 100m
9600 50m
38400 12m
115200 4m

but my uart use 3.3v and rs232 use 12v.

maybe uart is shorter than rs232.

i need to remake my cable.

--

this theread is very helpful for solving problem.

and because of (all of you)'s kindness, i do question easily.

I thank you for your help.

theNbomr 08-04-2009 09:14 AM

Quote:

Originally Posted by solo0805 (Post 3630258)
i check my cable, my cable's length is 60cm~70cm.

i found rs-232's wire length document.

it say
Baud Rate Max Cable Length
1200 400m
4800 100m
9600 50m
38400 12m
115200 4m

but my uart use 3.3v and rs232 use 12v.

maybe uart is shorter than rs232.

It sounds like there is some misunderstanding, and I feel compelled to clarify. A UART is a peripheral chip that serializes bytes for transmission and de-serializes bytes on reception. In RS-232, the voltage levels are specified as nominally +/- 12VDC. Even though your UART probably operates at 3.3VDC, there are line drivers and line receivers that convert the UART logic levels to RS-232 logic levels. If you are not using RS-232 voltage levels for your transmission lines, then the RS-232 specification becomes meaningless for your application. The RS-232 maximum length specification applies only where all of the other aspects spec are applied. These would include at least, signaling voltages, cable quality (probably specified as a capacitance or capacitance per foot), and line driver/receiver behavior, especially slew rate limiting. Violating any of these makes the max length spec meaningless.
So, are you actually using RS-232 electrical signaling (ie +/- 12 V logic levels)? If not, then I think we have found the answer to your problem. If you are using the high speed logic signals to drive your serial cable, then there are a few problems that will occur. Firstly, your line drivers, if they exist, will put fast rising and falling edges on the cables, and the high frequency content in these edges will easily propagate through capacitive coupling onto other conductors (ie cross-talk). Eliminating this phenomenon is the purpose of slew rate limiting built into the 'official' RS-232 line drivers. More likely, though, is that the capacitive load seen by ordinary 3.3V logic gates will prevent them from generating proper logic levels at all, and may cause them to lock at either logic state, oscillate, or alternate between error states. Last, and possibly worst, is that it sounds like you may be mixing RS-232 and standard logic levels, which may be harmful. If you drive a 3.3V input to +/- 12VDC using RS-232 drivers, it is likely to damage the input gate.
In summary, if you are not using proper RS-232 signaling throughout your system, you should make changes to do so.
--- rod.

Wim Sturkenboom 08-04-2009 10:05 AM

I don't think that there is a case of missing line drivers here as RS232 line drivers will also invert the signal and the data will always be wrong (regardless of speed).

Or they are missing at both sides ;)

theNbomr 08-04-2009 02:06 PM

You're right about the inversion. Whether there is an inversion or not, the problem seems difficult to explain. I cannot think of any way to explain that the null bytes seems to get through, but affect subsequent traffic in the byte stream. Unless, perhaps, there is some kind of device driver that is trying to do some kind of multi-byte character data translation (insert unicode/UTF-8/other appropriate jargon here). As the guy is in Korea, I think multi-byte character data becomes more common, if not default.
I am speculating from the name of his serial port (/dev/ttyAM1) that he is using some kind of embedded system single board computer. Sometimes these things come without line drivers, and use only TTL(ish) logic levels on the IO pins.
To solo0805: Is this a conventional PC motherboard, or a single board computer (ARM?). Do you have an oscilloscope at your disposal? It would be useful to view the input pins of the afflicted UART and/or line receiver.

--- rod.

solo0805 08-04-2009 09:27 PM

thanks for your answer.

and

Quote:

As the guy is in Korea, I think multi-byte character data becomes more common, if not default.
I am speculating from the name of his serial port (/dev/ttyAM1) that he is using some kind of embedded system single board computer. Sometimes these things come without line drivers, and use only TTL(ish) logic levels on the IO pins.
To solo0805: Is this a conventional PC motherboard, or a single board computer (ARM?). Do you have an oscilloscope at your disposal? It would be useful to view the input pins of the afflicted UART and/or line receiver.
i use both,

the whole system is like this.

Conventional PC(Windows system, program made by c#) ----(usb-uart converter)---- Rf module(3.3vinput, 3.3v ttl)

Arm Processor(linux system, program made by arm-linux-gcc) ----(uart connect 3.3v, 3.3vttl) ----rf module

rf is both zigbee.


and i don't have oscilloscope now.

i use driver. my mcu is ep9302.

but i didn't make it. i just modify arch/ep93xx/core.c(module initialize file) in kernel.

then i setting uart2, then i can use uart2.


and i didn't use rs232 level.

Wim Sturkenboom 08-05-2009 12:45 AM

I suppose you're trying to communicate from the PC to the ARM and the other way around over wireless.

Can you post links to datasheets for both the rf module and the usb-uart converter?


All times are GMT -5. The time now is 06:46 PM.