I am using C language and Linux as my programming platform. Right now I am learning some embedded programming. I am using a POS device for my practice session and my host is a Windows OS using a cygwin.
I created a simple application that will run in the target device that will read the data in the serial port and in the host side I created a simple application that will write the data in the serial port. Now my problem is when I am sending a data without 0x0a(LN) at the end of the buffer the target device will not receive that data. But I am not sure if that was sent or not. But when I put a 0x0a(LN) at the end of the buffer to send then the target device will receive that data.
Did I missed some configuration of my application? Or putting a 0x0a byte at the end of the tx buffer is the correct way.
Thanks
It sounds like your serial port (actually the 'terminal device' as far as Linux is concerned) may be in line-buffered mode. When setting it up with tcsetattr, be sure to clear c_lflag (you don't want ICANON). You should also check out the input/output flags that affect translation between CRLF and NL since you probably don't want that behavior either. Default terminal settings are oriented towards user/application interaction, not data transmission.
Sounds like it's doing line buffering. Do a flush after sending the data.
Related
I have a question linked to Linux and serial port.
I want to be able to receive and send messages to a dedicated serial port and to redirect it to another port (/dev/tty).
For the first part, I’m able to dialog with my hardware equipment without any problem, but I’m just wondering if it’s possible to intercept and redirect message coming from a serial port #1 to another port #2.
To give more context, I had used a GPS Antenna and NTP open source software for years.
Since 2018, the new GPS antenna protocol has modified the order of bytes in the message used by NTP to steer and now it’s not working anymore.
So my idea is to put a simple C program (middleware) which fixes this byte ordering; but I’m wondering if I have to build a kernel-specific module or if it can be done in another way. The NTP software uses the symbolic link to dialog.
Thanks for your help.
You can probably use a simple redirect, look here:
Pipe One Serial Port to Another in Linux
If the ports are in different rates you can use stty or perhaps screen to adjust: https://unix.stackexchange.com/a/117064
If you need it to be in c program to manipulate it you can use the following: https://stackoverflow.com/a/6947758/8901188
Using c it will need to run in an infinite loop so it can constantly read, manipulate and write the data.
I'm writing software to communicate with badly designed hardware. This hardware can communicate with linux pc (kernel 4.15) by RS485 line (9600 8N1) and it has very short timings: pc should reply in 2ms after receiving request from device.
I was able to solve this task using LOW_LATENCY flag and /sys/class/tty/ttySx/rx_trig_bytes file.
After opening port "rx_trig_bytes" file contents changes to "14", so I need write "1" to it after opening port to get good reply latency.
Is there any way to make this by API call or fix it after system boot / driver load ? Current realization looks ugly :(
Funny you find this way ugly, considering everything is a file in Unix, it should be the smart way.
I guess you are entitled to your own aesthetic sense.
If you want to make another buffer size the default you can always change it in the driver and recompile the kernel as suggested here.
I am trying to get a microcontroller to communicate with a Windows PC over serial port.
It looks to me like Windows is buffering the input on COM1 such that if I stop both programs running, then restart only the Windows program it is still receiving some output from the previous run of the microcontroller's program.
After I open COM1 can I some how flush its receive buffer before beginning to read? Is there a function call to do that?
I believe the function you are looking for is PurgeComm, to which you pass the HANDLE you got from CreateFile() when you opened the port. I'm not sure, but I believe the serial port is also automatically flushed each time you open it.
However, a better method is to use ReadFile (or ReadFileEx) until you encounter something meaningful. Serial protocols are always designed with one or more sync bytes for this very purpose. Unless you are writing a terminal program or similar, you will have to do like this anyhow, since the Windows PC will never be in sync with the microcontroller otherwise.
I just finished a small project written in C, where I read a data stream from a serial port and parse the incoming data.
The software is written for POSIX systems (using termios) and follows the standard steps to working with serial i/o
Opening the serial device using open()
Configuring communication parameters (termios)
Set blocking mode on file handle (fcntl)
Perform read() on serial interface.
Perform close() on serial interface when done.
Other than the socket parts, the code is straight ANSI C.
My question is, how involved would it be to make the code work on a windows platform.
The port would not be written by me, I'd only like to give an indication to others who might be interested in porting it (i.e. trivial, not so trivial, rip your eyes out insanity inducing).
Also if someone has Windows with "Windows Services for UNIX", would they be able to use the code without modifying it?
So, if anyone has experience with this could you please share.
It should be pretty easy to do. The names are very different, but the sequence of calls and concepts are very similar.
What you are looking for is the DCB structure which should be used with the SetComState() function to set baudrate, stopbits etc. Then use SetCommTimeouts() and set the timeout values in the COMMTIMEOUTS structure to make subsequent read calls blocking.
Here is a short introduction as a pretty PDF. (Backup.)
I am writing a C program in Linux which will read/write to/from a serial port. I know the data that needs to be read and written on the port but I don't have a serial port to currently test this with.
Is there any way to simulate a serial port? Would reading/writing to a file be sufficient? I can have one process write to the file while another process reads that data and writes back other data to the file. Or are there others tools that can be used to simulate a port?
Thanks
Serial ports on Linux are terminal devices. A close simulation is to create a pseudo-terminal pair; the program that normally talks to the serial port is instead told to open the slave side of the pseudo-terminal, and the simulator writes and reads from the master side.
The pty(7) man page has more information.
Despite being an old topic, and my answer is not exactly something the OP was looking for, I decided to share my experience, as someone else might come across it like I did. Instead of straightforward simulation, I used the software called Serial to Ethernet Connector to gain access to the specific device I needed to test the app with. Worked nicely for me.
A character device, even something as simple as normal stdin and stdout should work if you don't care about attributes specific to port devices.