Linux port and AsyncIO behaviour
Hi:
I have been using the Linux port with some success: while the multitasking environment has been performing well, I am having troubles with the AsyncIO interface.
I am using the AsyncIO to communicate with other applications running on a Linux machine, via pseudo terminals. The use of a pseudo terminal is dictated by third party applications that require serial access. I created an interface similar to the serial interface William Davy provided, which creates pseudo terminals.
Using the Linux port, I can receive data from the socket/serial/pseudo terminal file descriptors, using FreeRTOS. The ISR-like interface provided by the Linux port works very well for receiving.
However one issue I am seeing (which I believe is common to all sockets/serial interfaces) is that sending to the file descriptor used for receiving data is also intercepted by the signals used by the ISR (to detect incoming data). The signals hooked up to the file descriptors do not seem to differentiate between data coming from a different process (an external application writing to the socket/serial port), and data written by the freeRTOS port. I poked around with the Linux signal and I can’t seem to find a different type of signal to filter out activity on the file descriptors (so the ISR is only called when data is received from a different process).
Does this mean the AsyncIO interface is limited to receiving data only? Is there a workaround to allow sending and receiving data at the same time, on the same file descriptor?
Regards,
JS
Linux port and AsyncIO behaviour
Hi ARMinator,
I don’t recall this being a problem but it’s entirely feasible that I didn’t specifically test for it. Looking at the demo code, it seems like the the serial console echo task could easily be woken spuriously as the result of write and yet because there are no characters to read it simply ignores the interrupt.
I did use the Posix IPC message queues quite extensively for one project but they were always set-up uni-directionally meaning the senders weren’t interested in the interrupt on write, the single reader (for that pipe) would wake up and receive the characters. However, I had the benefit of writing the code on both sides of the pipe, meaning that it was easy to create multiple uni-directional pipes.
Looking at sparse information on O_ASYNC in ‘man fcntl’, it would seem to me that SIGIO is generated for read OR write on the file descriptor.
Would I be correct in saying that you are trying to write to the pseudo terminal from your FreeRTOS process, which immediately receives a SIGIO interrupt and you call read() and get back the characters that you just wrote, instead of those characters being picked up by the other process that is also supposed to be reading from the same terminal? Do you have any code that you could share with me to test this out?
Regards,
William
Linux port and AsyncIO behaviour
Hi William:
You are right in your understanding of the issue. It seems that any data sent from FreeRTOS on a file descriptor managed by the AsyncIO is also collected by the RX ISR (a bit like a local loopback).
I am attaching example code to simulate a bidirectional connection through a pseudo terminal, via the AsyncIO interface.
The loop project is to be compiled and linked with a FreeRTOS project using the pthread port. I have attached a freeRTOS config file for your convenience. As well I am adding a pseudo terminal interface to be copied to the AsyncIO folder of the pthread port.
The loop project is a single FreeRTOS task that creates a pseudo terminal, listens and echo back on a pseudo terminal. The pseudo terminal interface is built on a similar structure that you use to implement async IO through a serial interface.
The project will printf what pseudo port name was created (the path an external application should connect to)
I am also attaching a bare bones project (ptstest) which will send a string to the loop task via the pseudo terminal, and wait for the loop task to echo back the information.
To use it, type ptstest
When running ptstest I get the following output:
“./ptstest /dev/pts/11
Opening port /dev/pts/11
<48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A “Hello, World!
”
48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A “Hello, World! ” Which is expected. Data sent is also the data received back from the loop task.However from the FreeRTOS task, I have instrumented the ISR and I get the printouts provided in the file named output.txt (in the loop folder). It seems data is fed back into the ISR in a cyclic way, which led to loss of data. And overflow of the receive queue. Please let me know if this makes sense to you. And if you are having any troubles running the example code. To me it seems that there needs to be a way to differentiate between activity on the file descriptor coming from the process, and activity coming from outside of the process. Hope this makes sense. Regards, JS
Linux port and AsyncIO behaviour
Deleted, please see message below.
Linux port and AsyncIO behaviour
Hi ARMinator,
Thanks for the code, I got it compiling and running but it’s not happy on my Mac so I will have to use a Linux box instead. I’m traveling tomorrow and back at work Thursday/Friday so this might have to wait until the weekend.
I was looking at the ‘man pty’ page and there seem to be some interesting options using ‘ioctl’ but I think they have only been implemented in BSD kernels. Hmmm…
Worst case scenario, you can use a hardware loopback through physical serial ports, which I realize is a kludgy work around but it should get you up and running quickly.
Regards,
William
Linux port and AsyncIO behaviour
Hi William:
Thank you for looking into this. I will investigate further on the ioctl options available and see if any of interest is available on a Linux machine.
The hardware loopback might be impractical.
If you have the opportunity, please let me know if you are able to reproduce the loopback issue I am observing.
Regards,
JS
Linux port and AsyncIO behaviour
Hi William:
I looked further into this issue and found the problem (I believe). It is not related to the way the AsyncIO handles signals.
By default pseudo terminals seem to be configured to echo back to the sender. I disabled the echoing and the AsyncIO interface is working very well.
I apologize for involving you in this debugging case, as it turned out to be unrelated to the code you had provided.
Thank you again for a great contribution to FreeRTOS.
Regards,
JS