LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 05-28-2014, 08:04 AM   #1
sreeharsha1988
LQ Newbie
 
Registered: Apr 2014
Posts: 17

Rep: Reputation: Disabled
Serial tty devices


Hi,

I am trying to communicate with a serial device by sending packets to it using echo command and the device is responding as expected.

But I am trying to read the response the device is sending me back and that is where I am stuck.

I am able to see the response on another terminal running screen, the response is valid but the problem is that I am unable to catch that data. Moreover that data is in hex form and I need a way to type cast the data.

Any suggestions would be helpful for me.
 
Old 05-28-2014, 10:46 AM   #2
rtmistler
Moderator
 
Registered: Mar 2011
Location: Sutton, MA. USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu
Posts: 4,110
Blog Entries: 10

Rep: Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525
The simplest thing to do is exactly what you are doing, performing echo from one command prompt and performing cat on another command prompt. You can redirect the cat to a file to capture the responses completely, be they printable, versus not. Sounds like the characters are not printable, or you need translation to decode what you're seeing. So what I would do there is to write a short program to listen to the serial port, and output whatever is received from it in a coherent manner; which is to say that the program would decode the data and print it out in a read-able manner.

Minicom is a Linux terminal program, typically you have to run it using sudo, or as root; however I do not believe it gives you any better output translations than what you're seeing from the command prompt performing the cat. Perhaps there are other Linux terminal programs which will convert to HEX.

Here are some program tips for what I'd do in C if you were so inclined:

Substitute "/dev/ttyUSB0" for whatever serial resource you are using on your system:
Code:
int rdHandle;

if((rdHandle = open("/dev/ttyUSB0", O_RDONLY | O_NONBLOCK)) < 0) {
    // error situation, examine errno
}
Code:
char buffer[4096];
int ret;

if((ret = read(rdHandle, buffer, sizeof(buffer))) < 0) {
    // error situation, examine errno
    // NOTE: return can be 0 for no data
}
If ret was > 0, you now have some data. Decode it and print it out using printf().

Code:
int i;

for(i = 0; i < ret; i++) {
    printf("%02X ", buffer[i]);
}
 
1 members found this post helpful.
Old 05-29-2014, 01:43 AM   #3
sreeharsha1988
LQ Newbie
 
Registered: Apr 2014
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by rtmistler View Post
The simplest thing to do is exactly what you are doing, performing echo from one command prompt and performing cat on another command prompt. You can redirect the cat to a file to capture the responses completely, be they printable, versus not. Sounds like the characters are not printable, or you need translation to decode what you're seeing. So what I would do there is to write a short program to listen to the serial port, and output whatever is received from it in a coherent manner; which is to say that the program would decode the data and print it out in a read-able manner.

Minicom is a Linux terminal program, typically you have to run it using sudo, or as root; however I do not believe it gives you any better output translations than what you're seeing from the command prompt performing the cat. Perhaps there are other Linux terminal programs which will convert to HEX.

Here are some program tips for what I'd do in C if you were so inclined:

Substitute "/dev/ttyUSB0" for whatever serial resource you are using on your system:
Code:
int rdHandle;

if((rdHandle = open("/dev/ttyUSB0", O_RDONLY | O_NONBLOCK)) < 0) {
    // error situation, examine errno
}
Code:
char buffer[4096];
int ret;

if((ret = read(rdHandle, buffer, sizeof(buffer))) < 0) {
    // error situation, examine errno
    // NOTE: return can be 0 for no data
}
If ret was > 0, you now have some data. Decode it and print it out using printf().

Code:
int i;

for(i = 0; i < ret; i++) {
    printf("%02X ", buffer[i]);
}
I have a C code which will communicate with the device as desired but I am looking at the ways in which I can communicate with the device using shell scripting alone. This is because while trying to execute certain c-programs from a shell scripts I am unable to make the script wait until the program is completely executed.
 
Old 05-29-2014, 05:12 AM   #4
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 8,129

Rep: Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272
you may try:
a=$(od -t x1 <serial device>)

and you will get the result in a (just you need to process it), but it also depends how many bytes do you want to evaluate.
 
Old 05-29-2014, 08:00 AM   #5
rtmistler
Moderator
 
Registered: Mar 2011
Location: Sutton, MA. USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu
Posts: 4,110
Blog Entries: 10

Rep: Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525
Quote:
Originally Posted by sreeharsha1988 View Post
I have a C code which will communicate with the device as desired but I am looking at the ways in which I can communicate with the device using shell scripting alone. This is because while trying to execute certain c-programs from a shell scripts I am unable to make the script wait until the program is completely executed.
Having trouble understanding that statement. For instance cat is a C program, as are many of the binary commands available in the shell. Fact is you can implicitly create a new shell command merely by ensuring that a compiled C program is in your path variable, or you can copy the binary executable to something like /usr/bin or /usr/sbin. When you've had this problem, have you invoked the C program in the background? Or was it a C program not structured to exit, but instead stay operating in a loop?
 
Old 05-29-2014, 08:27 AM   #6
sreeharsha1988
LQ Newbie
 
Registered: Apr 2014
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by rtmistler View Post
Having trouble understanding that statement. For instance cat is a C program, as are many of the binary commands available in the shell. Fact is you can implicitly create a new shell command merely by ensuring that a compiled C program is in your path variable, or you can copy the binary executable to something like /usr/bin or /usr/sbin. When you've had this problem, have you invoked the C program in the background? Or was it a C program not structured to exit, but instead stay operating in a loop?
The C Program which I am invoking with the shell script is performing a series of operations divided into individual cases divided in the code. The program runs in a loop as long as i desire and exits if I ask the code to exit. The problem is if I am running the code using the terminal normally the script and the program it is invoking are executing as they should but if I copy the script in init.d and create a symbolic link to the script in rc2.d folder in /etc to make this script run on boot up the script is invoking the code but it is not waiting till the c program is completely executed and this is causing undesired outcomes.

So to avoid calling a c program to perform the tasks I wish I am preferring to implement my code functionality in shell script completely.
 
Old 05-29-2014, 08:33 AM   #7
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 8,129

Rep: Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272
actually your explanation is not clear (for me). Probably you missed something, or I misunderstood something.
The program you invoked should work in the same way any time, therefore its execution must not depend on that fact (if it was executed from a shell or by an init script).
I would add set -xv at the beginning of your script to see what's happening and compare the two cases. You will see what causes the differences...
 
Old 05-29-2014, 10:47 AM   #8
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,604

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
One of the things to watch out for with using serial devices is the thing on the other end of the serial device...

Does it use modem signals?
Does respond to cts/rts signals?

One of the things that happens is that cts is off (not clear to send) if the terminal is closed... thus the device stops.

Having the serial line open (ie cat) allows another process to send data, and the response to be read. But note: this takes two processes.

Serial lines are asynchronous devices. Normal commands are synchronous. Now you CAN get the effect by opening ANOTHER file desriptor (not stdin/stdout) to the terminal (see bash manpage for redirection for other than file descriptors 0,1,2). You can then use this file descriptor to send data, and read responses (also bash coprocesses may help, by having a coprocess ready to read a response, the the other process sends a string).
 
Old 05-30-2014, 12:42 AM   #9
sreeharsha1988
LQ Newbie
 
Registered: Apr 2014
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by pan64 View Post
actually your explanation is not clear (for me). Probably you missed something, or I misunderstood something.
The program you invoked should work in the same way any time, therefore its execution must not depend on that fact (if it was executed from a shell or by an init script).
I would add set -xv at the beginning of your script to see what's happening and compare the two cases. You will see what causes the differences...
This shell script is running on an embedded SOC board (zedboard) and this board is running a linux kernel based on Ubuntu, If I execute the script from the terminal when the system is completely booted up this works well. The program gets invoked and I am able to communicate with the device which is an UART based finger-print reader. The C program communicates with my device serially and determines if a user is authenticated or not and then this program returns the control to the script. Problem is that if this is placed on init.d script the program starts, configures the serial ports but the device will not respond, some times the device responds and I can communicate with the program and then abruptly this communication ends and the script stops to execute, If the device is plugged out my program ends prematurely and my script continues.

More surprisingly this same script and the same program works as expected on raspberry pie which is running a linux kernel based on debian.

This is making me think of what is gone wrong on zedboard and I could not identify the problem and hence I am exploring the ways to either execute the program forcefully using a while loop or implementing the entire c code in shell script.
 
Old 05-30-2014, 02:09 AM   #10
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 8,129

Rep: Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272
I see, so probably it runs too early, the system has not been fully initialized?
How it is configured in init.d? Probably it should be executed a bit later?
 
Old 05-30-2014, 02:32 AM   #11
sreeharsha1988
LQ Newbie
 
Registered: Apr 2014
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by pan64 View Post
I see, so probably it runs too early, the system has not been fully initialized?
How it is configured in init.d? Probably it should be executed a bit later?
I configured it to run with least possible priority so that it runs after all the drivers are completely loaded.
 
Old 05-30-2014, 02:39 AM   #12
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 8,129

Rep: Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272Reputation: 2272
in that case I can suggest only to insert set -xv in the beginning of the script, save the log and check it. Probably you will find some useful info in it.
 
Old 05-30-2014, 09:04 AM   #13
rtmistler
Moderator
 
Registered: Mar 2011
Location: Sutton, MA. USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu
Posts: 4,110
Blog Entries: 10

Rep: Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525Reputation: 1525
Quote:
Originally Posted by sreeharsha1988 View Post
I configured it to run with least possible priority so that it runs after all the drivers are completely loaded.
No such concept of "priority" where a script is lowest so that it "allows" drivers to load, you run them given a sequence value to ensure that other startup scripts run before they do. The flow of the init is governed by the run level and the numbers following the 'S' in your symbolic link. Furthermore, there are things you can do in your script to test the availability of the /dev/tty<resource> you require.

Code:
# Your script - example
/etc/init.d/my-script.sh

# A sample symbolic link in the /etc/rc5.d directory, likely where it should be by the way
/etc/rc5.d/S99my-script

# Which when the details are viewed shows as
lrwxrwxrwx 1 root root ## dd mon yy S99my-script -> ../init.d/my-script.sh
Therefore the fact that it is in runlevel 5 means it runs as part of loading that runlevel, which should be the most typical one for a user script which also requires that most drivers be loaded.

The 'S' is for Starting the script, as opposed to a 'K' which you would use in say runlevels 2, 4, or 6 as the system is going down if you needed to cleanup anything.

The '99' is the important part; which is the numerical ordering of when the script gets run. I honestly don't know if you can use one, three, or more digit numbers; I've always used 2 digit numbers, but they work in counting order, therefore 01, 02, 03, 04, ... 97, 98, 99 would be run in sequence; if symbolic links existed for every number.

I should also state some added ignorance on my part which is that there is also rcS.d (Letter S) and I've successfully placed start scripts there versus the rc5.d (number 5) directory. I don't know the reason, but have heard that use of the rcS.d (Letter S) tree is discouraged.

Last edited by rtmistler; 05-30-2014 at 09:06 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
serial port without tty? alirezan1 Linux - Newbie 2 10-29-2013 05:04 PM
Is a USBtty (USB serial port) treated the same as tty (normal serial port) in C? spudgunner Programming 1 11-12-2010 02:19 PM
What are pseudo-tty devices? pinga123 Linux - Newbie 2 09-21-2010 09:42 AM
[SOLVED] Serial Programming - Multiple interruptions for serial devices on real-time Linux. santiagocasti Programming 5 05-06-2010 05:34 AM
Serial Ports (tty´s) aqoliveira Linux - Hardware 4 06-21-2002 11:06 AM


All times are GMT -5. The time now is 08:24 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration