Serial ports again

Hi!

Sorry for starting another ‘help me with serial port’ post but I’m quite confused and after reading a lot on the web and on openqnx I’m still left with no solution for my problem:

basically I need my application to read and write from a serial port.

Writing works fine:

serialport0 = open ("/dev/ser0",O_RDWR | O_NOCTTY | O_NDELAY);
write(serialport0,“smt”,3);

but reading:

read(serialport0,serialbuf,sizeof(serialbuf))

Isn’t working ( It returns a value =< 0 )
:confused:

Any ideas? Thanks!

I don’t think QNX uses O_NDELAY (or maybe it’s implemented with O_NONBLOCK).
When read() returns -1 what is errno set to?

how can I check that? :unamused:

I’m still stuck :frowning:

My serial ports are configured at startup
devc-sersci -c32000000/16 -b115200 -s -E -e -u0 sh7760scif0 -u1 sh7760scif1 -u2 sh7760scif2&

I can write to them but I get always -1 when I read from them. I wonder whether that could be connected with the software/hardware control. But I have no idea what to try next. I’m sitting for hours on that :frowning:

I also tried to disable Software and Hardware Flow - but still the same writing OK but I can’t read from it :frowning: strange

The errno mechanism is the standardized way to discover what went wrong when (most) system library calls encounter error conditions. Read the docs on errno.

You’ll need to do something like this in your code:

#include <errno.h>
#include <string.h>

if( read(portfd,buf,N) < 0 )
printf( “read failed, errno = %d [%s]\n”, errno, strerror(errno));

Thanks!

The error is:

“read failed, errno = 11 [Resource temporary unavailable]”

:confused: what could that be?

Look in the docs under read() and errno. EAGAIN means that O_NONBLOCK is set and the process would be delayed in the read operation so read() returned right away. In other words, no data was available when read() executed so rather than blocking and waiting it returned an indication that no data was ready to be read.

That’s the behavior requested when you open the port O_NONBLOCK (O_NDELAY). If you remove that from your open call the read() will block until data is available.

hm

If I remove the nonblock flag and my application freezes until any data are available. But even though I send data noting is being received :frowning:

If you do

cat < /dev/serN

on your target, and send some data and enter from the other machine with a terminal program, does anything show up on the target? If not then either the serial port parameters are mismatched between the two machines, or the cables are wrong (you are using a proper NULL modem cable, right?), or there is something wrong with the serial port driver on the target (started with wrong arguments, IPL not initializing hardware correctly, something else is interfering with hardware, …)

I did that

used this configuration:
devc-sersci -c32000000/16 -s -E -b115200 -e -u0 sh7760scif0 -u1 sh7760scif1 -u2 sh7760scif2&

the serial2 by default a ksh terminal.

But basically I did what you suggested.
and I received data from serial port 2 but not from the others :frowning: don’t have a clue why.
they were configured in the same way.

Is this a custom board?

I don’t know anything about your board or processor but generally you might start dumping some of the serial registers and seeing how things are being initialized. Also make sure the interrupts are enabled on those non-working ports by dumping the interrupt setup registers.

Have you looked in the syslog to see if any errors are logged?

I looked in slog but nothing is there.

My board is sh7760.
It has a one serial port with a connector on it and that one works fine.
but the two other which are only in a form of pins are not receiving data.

How can I get the configuration register of the ports dumped?

How do you know that the pins are not receiving data? First things first, make sure the cable is right.

If this were my board I’d hook up a scope or serial port analyzer to make sure there is data on the wires.

Here’s another thought.

Does that board have any configuration jumpers or switches to enable, disable, or change the addressing of those non-working serial ports?

Well - I used the same cable which I know is working for the port 2 ( both reads and writes ) - so the cable is probably ok.

The board specification isn’t saying anything about additional jumpers.

the difference between port 2 and the other 2 is that they have no transiver installed and I need to attach a small circuit to them.

But if it was not working at all I would say that is smt to do with the hardware but as it writes to those ports but its not receiving anything I’m really confused :frowning:

I checked the Serial2 which normaly I use a a system console with a cable that I know works and when I did it from code I had the same thing
writing ok reading NO :frowning:

maybe smt is wrong with my code:

ThreadCtl(_NTO_TCTL_IO,0);
serialport2 = open ("/dev/ser2",O_RDWR | O_NOCTTY |O_NONBLOCK);
write(serialport2,“serial 2 open”,19);

… //in the main loop:

if( read(serialport2,serialbuf,20) >0 )
{
sprintf(buf, “mes rec [%s]\n”, serialbuf);
write(serialport2,buf,strlen(buf));
}

:question: what could be wrong?

Do you have a hardware debugger?

You could send a byte to the port from the host while watching the RX register.

If no byte appears either the host is not sending it, or the cabling is bad/wrong, or there is something broken between the connector and the UART, or the UART is bad.

If the byte does show up in the RX register then at least you know it’s something in the software on the target.

Sorry, maybe I misunderstood you.

Are you saying that the port works bidirectionally if used with a terminal shell but not if you try to do it with your code?

yesterday I managed to get one of the port working from console and from code - everything is fine.
The other to however the same - send data but not receiving.

How can I check RX register?

These serial ports are integrated into the cpu chip? You need the register map for chip. Find the address of the RX register of the non-working port. Make sure the serial port is enabled (whatever the chip requires to enable the port, sometimes it needs the clock to be enabled or power management may disable it, or???). Send a byte to the target and then either use a hardware debugger to look at the register (easiest) or write some test code to dump that register. If you use test code you’ll have to kill the serial driver before running your code so they don’t interfere with each other.