Getting notification that the serial port is ready to be read from - c++

I have to write a C++ application that reads from the serial port byte by byte. This is an important need as it is receiving messages over radio transmission using modbus and the end of transmission is defined by 3.5 character length duration so I MUST be able to get the message byte by byte. The current system utilises DOS to do this which uses hardware interrupts. We wish to transfer to use Linux as the OS for this software, but we lack expertise in this area. I have tried a number of things to do this - firstly using polling with non-blocking read, using select with very short timeout values, setting the size of the read buffer of the serial port to one byte, and even using a signal handler on SIGIO, but none of these things provide quite what I require. My boss informs me that the DOS application we currently run uses hardware interrupts to get notification when there is something available to read from the serial port and that the hardware is accessible directly. Is there any way that I can get this functionality from a user space Linux application? Could I do this if I wrote a custom driver (despite never having done this before and having close to zero knowledge of how the kernel works) ??. I have heard that Linux is a very popular OS for hardware control and embedded devices so I am guessing that this kind of thing must be possible to do somehow, but I have spent literally weeks on this so far and still have no concrete idea of how best to proceed.

I'm not quite sure how reading byte-by-byte helps you with fractional-character reception, unless it's that there is information encoded in the duration of intervals between characters, so you need to know the timing of when they are received.
At any rate, I do suspect you are going to need to make custom modifications to the serial port kernel driver; that's really not all that bad as a project goes, and you will learn a lot. You will probably also need to change the configuration of the UART "chip" (really just a tiny corner of some larger device) to make it interrupt after only a single byte (ie emulate a 16450) instead of when it's typically 16-byte (emulating at 16550) buffer is partway full. The code of the dos program might actually be a help there. An alternative if the baud rate is not too fast would be to poll the hardware in the kernel or a realtime extension (or if it is really really slow as it might be on an HF radio link, maybe even in userspace)
If I'm right about needing to know the timing of the character reception, another option would be offload the reception to a micro-controller with dual UARTS (or even better, one UART and one USB interface). You could then have the micro watch the serial stream, and output to the PC (either on the other serial port at a much faster baud rate, or on the USB) little packages of data that include one received character and a timestamp - or even have it decode the protocol for you. The nice thing about this is that it would get you operating system independence, and would work on legacy free machines (byte-by-byte access is probably going to fail with an off-the-shelf USB-serial dongle). You can probably even make it out of some cheap eval board, rather than having to manufacture any custom hardware.

Related

NTPD synchronization with 1PPS signal

I have an AHRS (attitude heading reference system) that interfaces with my C++ application. I receive a 50Hz stream of messages via Ethernet from the AHRS, and as part of this message, I get UTC time. My system will also have NTPD running as the time server for our embedded network. The AHRS also has a 1PPS output that indicates the second roll-over time for UTC. I would like to synchronize the NTPD time with the UTC. After some research, I have found that there are techniques that utilize a serial port as input for the 1PPS. From what I can find, these techniques use GPSD to read the 1PPS and communicate with NTPD to synchronize the system time. However, GPSD is expecting a NMEA formatted message from a GPS. I don't have that.
The way I see it now, I have a couple of optional approaches:
Don't use GPSD. Write a program that reads the 1PPS and the Ethernet
message contain UTC, and then somehow communicates this information
to NTPD.
Use GPSD. Write a program that repackages the Ethernet message into
something that can be sent to GPSD, and let it handle the
interaction with NTPD.
Something else?
Any suggestions would be very much appreciated.
EDIT:
I apologize for this poorly constructed question.
My solution to this problem is as follows:
1 - interface 1PPS to RS232 port, which as it turns out is a standard approach that is handled by GPSD.
2 - write a custom C++ application to read the Ethernet messages containing UTC, and from that build an NMEA message containing the UTC.
3 - feed the NMEA message to GPSD, which in turn interfaces with NTPD to synchronize the GPS/1PPS information with system time.
I dont know why you would want drive a PPS device with a signal that is delivered via ethernet frames. Moreover PPS does not work the way you seem to think it does. There is no timecode in a PPS signal so you cant sync the time to the PPS signal. The PPS signal is simply used to inform the computer of how long a second is.
there are examples that show how a PPS signal can be read in using a serial port, e.g. by attaching it to an interrupt capable pin - that might be RingIndicator (RI) or something else with comparable features. the problem i am seeing there is that any sort of code-driven service of an interrupt has its latencys and jitter. this is defined by your system design (and if you are doing it, by your own system tailored special interrupt handler routine - on a PC even good old ISA bus introduced NMI handlers might see such effects).
to my best understanding people that are doing time sync on a "computer" are using a true hardware timer-counter (with e.g. 64 bits) and a latch that gets triggered to sample and hold the value of the timer on every incoming 1PPS pulse. - folks are doing that already with PTP over the ethernet with the small variation that a special edge of the incoming data is used as the trigger and by this sender and receiver can be synchronized using further program logic that grabs the resulting value from the built in PTP-hardware-latch.
see here: https://en.wikipedia.org/wiki/Precision_Time_Protocol
along with e.g. 802.1AS: http://www.ieee802.org/1/pages/802.1as.html
described wikipedia in section "Related initiatives" as:
"IEEE 802.1AS-2011 is part of the IEEE Audio Video Bridging (AVB) group of standards, further extended by the IEEE 802.1 Time-Sensitive Networking (TSN) Task Group. It specifies a profile for use of IEEE 1588-2008 for time synchronization over a virtual bridged local area network (as defined by IEEE 802.1Q). In particular, 802.1AS defines how IEEE 802.3 (Ethernet), IEEE 802.11 (Wi-Fi), and MoCA can all be parts of the same PTP timing domain."
some article (in German): https://www.elektronikpraxis.vogel.de/ethernet-fuer-multimediadienste-im-automobil-a-157124/index4.html
and some presentation: http://www.ieee802.org/1/files/public/docs2008/as-kbstanton-8021AS-overview-for-dot11aa-1108.pdf
my rationale to your question is:
yes its possible. but it is a precision limited design due to the various internal things like latency and jitter of the interrupt handler you are forced to use. the achievable overall precision per pulse and in a long term run is hard to say but might be in the range of some 10 ms at startup with a single pulse to maybe/guessed 0,1 ms. - doing it means proving it. long term observations should help you unveiling the true practical caps with your very specific computer and selected software environment.

What is an acceptable MIDI bandwidth over USB?

I am working on a MIDI effect (a VST plugin which modifies incoming MIDI generates new data and forwards it out) using the Juce Framework in C++. I see that it's technically possible to generate a new MIDI message with EVERY sample making my stream of MIDI flow at 16 to 24 bits 41,000 times a second or more. This seems entirely impossible for MIDI hardware to handle.
Is there any guideline or rule I must adhere to when when I decide on my bandwidth for MIDI over USB to hardware synths, new and old?
EDIT:
I should add that for what I am trying to do, higher bandwidth would help, but should work with hardware such as the Arturia Minibrute. I am attempting to do novel things like apply envelopes and LFOs to the modulation and pitch wheel.
MIDI over DIN cables runs at 31250 bits/s, i.e., 3125 bytes/s.
The USB MIDI specification does not specifiy any bandwidth, but the underlying USB bulk transfer protocol implicitly allows the receiving device to decide when to accept new packets.
In other words, the USB MIDI device can decide how fast it runs, but there is no easy mechanism to determine this limit (especially if your OS just drops MIDI messages that the device driver cannot deliver fast enough).
USB/MIDI interfaces run at exactly 3125 bytes/s.
USB MIDI devices where no 'real' MIDI interface is involved might be able to run faster; for example, my SC-8820 can process about 10 KB/s.
In practice, you cannot know what hardware sits behind some generic MIDI port.
You should use the 3125 bytes/s limit unless you have special knowledge about the device.

Modify time until DBT_DEVICEREMOVECOMPLETE is sent

Is there a way to trigger the USB Device Discovery of Windows, such that removed devices are detected faster?
I have a USB Serial modem that I unplug (the USB plug, not the serial one). I want to detect the DBT_DEVICEREMOVECOMPLETE event which is sent as soon as the unplugging is detected (That's what I assume). The detection of the Event works as desired, it is sent sometimes 1s after removal, sometimes several minutes after removal.
Is there a way to decrease the refresh interval, or another way to make this event getting sent faster?
Well, the problem here is that DBT_DEVICEREMOVECOMPLETE is sent after Windows decides it has detected the removal, and you can't influence that, at least not in the general case. There are various things that make Windows do this faster or slower (type of device, current "data flow" with the device, the device itself), and it also varies between OS versions. What I found helps to some degree in some of cases is to remove, from the Registry, references to USB devices that were plugged into that USB port before (there are various utilities for this).
At the extreme, since this is a Windows Broadcast message (non-queued), there will not be another one sent in until the previous is processed. Thus, you may not receive it at all! To solve that, keep message handling fast and simple and don't set a breakpoint there while debugging.
Also, having a separate Windows and Thread for the specific purpose of handling USB device arrival/removal notifications may help.
But, from my experience, polling will not help, as the main problems seems to be in the criteria Windows uses to detect the removal. The time from that event until you receive the message is small. Of course, in your case this may not be true - to find out, use a tool like SysInternals Process Monitor. Depending on what you see going on there, there may be something you can do to make it faster.

Can I write Ethernet based network programs in C++?

I would like to write a program and run it on two machines, and send some data from one machine to another in an Ethernet frame.
Typically application data is at layer 7 of the OSI model, is there anything like a kernel restriction or API restriction, that would stop me from writing a program in which I can specify a destination MAC address and have some data sent to that MAC as the Ethernet payload? Then write a program to listen for incoming frames and grab the frames from a specified source MAC address, extracting the payload of data from the frame?
(So I don't want any other overhead like IP or TCP/UDP headers, I don't want to go higher than layer 2).
Can this be done in C++, or must all communication happen at the IP layer, and can this be done on Ubuntu? Extra love for pointing or providing examples! :D
My problem is obviously I'm new to network programming in c++ and as far as I know, if I want to communicate across a network I have to use a socket() call or similar, which works at an IP layer, so can I write a c++ program to work at OSI layer 2, are there APIs for this, does the Linux kernel even allow this?
As you already mentioned sockets, probably you would just like to use a raw socket. Maybe this page with C example code is of some help.
In case you are looking for an idea for a program only using Ethernet while still being useful:
Wake on LAN in it's original form is quite simple. Note however that most current implementations actually send UDP packets (exploiting that the receiver does not parse for packet headers etc. but just a string in the packet's payload).
Also the use of raw sockets is usually restricted to privileged users. You might need to either
call your program as root
or have it owned by root and setuid bit set
or set the capability for creating raw socket using setcap CAP_NET_RAW+ep /path/to/your/program-file
The last option gives more fine grained privileges (just raw sockets, not write access to your whole file system etc.) than the other two. It is still less widely known however, since it is "only" supported from kernel 2.6.24 on (which came with Ubuntu 8.04).
Yes, actually linux has a very nice feature that makes it easy to deal with layer 2 packets. You can use a TAP device, which allows your userspace program to read/write ethernet traffic through the kernel.
http://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/Documentation/networking/tuntap.txt
http://en.wikipedia.org/wiki/TUN/TAP

controling individual pins on a serial port

I know that serial ports work by sending a single stream of bits in serial. I can write programs to send and receive data from that one pin.
However, there are a lot more other pins on the serial port connection that normal aren't used but from documentation all seem to have some sort of function for signalling as opposed to data transfer.
Is it possible in any way to cause the other pins that are not used for direct data transfer to be controlled individually? If so, how would i go about doing that?
EDIT: more information
I am working with a modern CPU running windows 7 64-bit on an intel core i7 870 processor. I'm using serial to usb ports because its imposable for me to do anything directly with a usb port and my computer does not come with serial ports and also for some inexplicable reason i have a bunch of these usb to serial port adapters lying around.
My goal is to control mutipul stepper motors (200 steps per rotation, 4 phase motors). My simple circuitry accepts single high pulses and interprets it as a command to cause the motor to rotate one step. The circuit itself will handle the power supply and phase switching. I wish to use the data transfer pin to send the rotation signals (we can control position and velocity by altering the number of high pulses and frequency of high pulses through the pin, however there is no real pulse width modulation).
I have many motors to control but they do not need to be controlled simultaneously. I hope to use the rest of the pins and run them through a simple combination logic circuit to identify which motor is being moved and which direction it is to move in. This is part of the power switching circuitry.
The data transfer pin will operate normally at some low end frequency. However, i want to control the other pins to allow me to give a solid on or off signal (they wont be flipping very quickly, only changes when i switch to controlling another motor).
Based of the suggestion of Hans Passant , I'd like to suggest that you use an Arduino instead of an USB-to-serial converter. The "Duemilanove" is an Arduino-based board that provides 6 PWM outputs (as well as 8 other digitial I/Os and 6 analog). Some more specialized boards might be even cheaper (Arduino Pro Mini, $15 in volume, some soldering required).
Using the handshaking pins to send data can work very well, though probably not on a multitasking OS, it's just very processor intensive (because the port needs to be polled constantly) and requires some custom cables. In fact, back in the day, this is exactly how Laplink got such high transfer rates over serial connections (and why to get those rates you needed a special 'Laplink' cable). And you need both sides of hte link to be aware of what's going on and be able to deal with the custom communications. Laplink would send a packet of data over both the normal UART pins while trying to send data from the other end of the packet over the handshaking pins. If the correct cable wasn't used (or there was some other problem with sending over the handshaking pins) there was no problem - all the data would just get send normally.
Embedded developers might know this as 'bit banging' - often on small embedded systems there's no dedicated UART circuitry - to get serial communications to work they have to toggle a general I/O pin with the correct timing. The same can be done on a UART's handshaking pins. But like I said, it can be detrimental to the system if other work needs to be done.
You can use DTR and RTS only, but that is four possible states. You do need to be careful that the device on the other end uses TTL levels. At he end of this link Serial there are tips on hardware if you need it.
What kind of data rate are you thinking of when you say high frequency? What kind of serial port do you have? With the old 9 pin connectors on the back of the computer the best you can do is around 115Kbps. With a USB adapter I have done test where I could push close to 1Mbps through the port.
Here's an article from Microsoft that goes into great detail on how to work with serial ports:
http://msdn.microsoft.com/en-us/library/ms810467.aspx
It mentions EscapeCommFunction for directly controlling the DTR line.
Before you check out this information, I'm joining in with the others that say a serial port is inappropriate for your application.
I´ve been trying to find an answer to your question for 3 hours, seems like there is no "simple way" to get a simple boolean signal from a computer...
But, there is always a way, and jet, as simple (maybe even stupid) as this may sound, have you considered using the audio jack connector as an output?, It is stereo so you would have 2 outputs available,the programming would is not that difficult. and you don#t need to buy expensive shit to make it work.
If you also need an input, just disassemble a mouse... and bridge the sensors to the servos, probably the most cheap and easiest way of doing it...
Another way would be using the leds for the Num-lock, caps-lock and the dspl-lock on the keyboard, these can be activated using software, and you just need to take a cheap external keyboard, and use the connectors for these 3 leds.
you are describing maybe a parallel port - where you can set bit patterns all at once - then toggle the xmit line to send it all...
Lets take a look from the "bottom up" point of view:
The serial port pins
Pins on the serial port may be connected to a "controller" or directly connected to the processor. In order for the processor to have access (control) the pins, there must be an electrical connection from the pins to the processor. If not, the processor nor the program can control the pins.
Using a serial controller
A controller, such as a USART, would be connected between the serial port and the processor. The controller may function as to convert 8 parallel data bits into serial bitstream. In the big picture, the controller must provide access to the port pins in order for them to be controlled. If it doesn't, the pins can't be accessed. The controller must be connected to the processor in order to control the pins if a controller is connected.
The Processor and the Serial port
Assuming that the pins you want to control are connected to the processor, the processor must be able to access them. Sometimes they are mapped as physical addresses (such as with an ARM processor), or they may be connected to a port (such as the intel 8086). A program would access the pins via a pointer or using a i/o instruction. In some processor, the i/o ports must be enabled and initialized before they can be used.
Support from the OS
Here's a big ticket item: If your platform has an Operating System, the Operating System must provide services to access the pins of the serial port. The services could be a driver or an API function call. If the OS doesn't provide services, you can't access the serial port pins.
Permission from the OS
Assuming the OS has support for the serial port, your program must now have permission to access the port. In some operating systems, permission may only be granted to root or drivers and not users. If your account does not have permission to access the pins, you are not going to read them.
Support from the Programming Language
Lastly, the programming language must have support for the port. If the language doesn't provide support for the port you may have to change languages, or even program in assembly.
Accessing the "unused" pins of a serial port require extensive research into the platform. Not all platforms have serial ports. Serial port access is platform dependent and may change across different platforms.
Ask another, more detailed question and you will get more detailed answers. Please provide the kind of platform and OS that you are using.