I'm trying to make my program robust against network disconnections. Right now, if I disable ethernet network from OS (I'm over Ubuntu 11.10, but I guess that should not matter), my sockets recover once the network is enabled again and everything goes all right.
Since now I have supposed this test was the same as unpluging the ethernet cable. But it is not, since my program is suddenly terminating when doing this.
I want to know what's the difference between these two scenarios, and how to detect both of them. I'm using QTcpSockets from Qt and C++.
Also, when wifi is no longer detected, I guess it's equal to unplugging ethernet cable, while disabling it at the OS is equivalent to disable ethernet network. Am I right?
When the driver is enables, it means there is a program running at the OS kennel that manages different scenarios. For example, on cable disconnect, there is a link drop. And entering to low power mode.
When disabling the driver either there is a firmware on your device that could manage the device on, or there device will be off.
Related
I'm quite new to programming at linux and its file-based communication.
I need to create a virtual modem (or modem emulator) at linux machine. The idea is that the software module that sends commands to hardware modem on an FPGA,
At FPGA:
SoftwareModule <= ttyACM => HardwareModem
What I need to achieve at my computer:
SoftwareModule <=> MyModemEmulator acting like a fake UART
Purpose is that the software module can be tested on a linux machine where I have a fake software modem UART(?) port. So the software module sends the modem commands and my fake modem module catches and responds accordingly. So my module will be actually acting like a hardware modem.
What could be the steps I need to take for that? I'm quite new to working with serial ports and don't have deep knowledge of linux or hardware stuff.
I have come across 'socat' but I'm not sure if that can really serve the purpose.
So far I have only learned how to create a basic file system with FUSE (as it was suggested by someone), but I'm not sure how can I use it for my purpose. I'm not looking for a proprietary solution, and not looking for windows based solution either.
Please guide me to the right directions.
Thank you !
Creating a Fake Serial Port to Emulate Modem
What you refer to as a "serial port" in Linux is actually a serial terminal with many software layers.
Study Linux serial drivers, and the termios man page for salient functions that need to be emulated.
And you have not even considered how to factor in the USB component of the communication path.
At FPGA:
SoftwareModule <= ttyACM => HardwareModem
...
My computer with ubuntu does not have ttyACM
A /dev/ttyACMx device node is only created when a USB serial gadget is connected to the host.
So it's not surprising that you cannot find such a device node.
What I need to achieve at my computer:
SoftwareModule <=> MyModemEmulator acting like a fake UART
You have stated the issue poorly, since you (misguidedly) think that a "fake UART" (integrated with your "MyModemEmulator") is the appropriate solution.
Do not try to emulate both a serial terminal and an external modem on the Ubuntu host, since you are "quite new to programming at linux and serial ports" and the task of accurately emulating a serial terminal is risky and expensive.
What your goal should be is:
SoftwareModule <= ? => MyModemEmulator
and the question is "what is needed in the middle to interface these two units?".
IOW you have posted an XY problem.
There are a plethora of SBCs (single board computer) that have a USB gadget port and can be configured as a USB serial gadget that uses CDC ACM.
Since the actual "hardware modem on an FPGA" will use a USB CDC ACM connection, you should consider using an actual /dev/ttyACMx serial terminal, and emulating just the external device ("hardware modem") with a SBC.
In other words, instead of trying to achieve:
SoftwareModule <=> MyModemEmulator + fake USB serial terminal
it should be much easier to use existing interfaces and implement:
SoftwareModule <= USB => emulated HardwareModem
with a SBC running your Linux application for modem emulation using /dev/ttyGS0 (a USB serial terminal on the gadget end).
By using an actual USB CDC ACM connection and not implementing the "fake USB serial terminal", this approach eliminates an entire layer of SW+HW emulation and its possible false test results.
Addendum
If the use and/or cost of embedded Linux on a SBC concerns you, then there is an alternative scheme to emulate the "hardware modem" on your Ubuntu PC host instead of the SBC using a USB-to-RS232-to-USB connection.
Acquire a pair (i.e. quantity 2) of USB-to-RS232 adapters and a (very short) null-modem cable.
Connect the DB-9 ends of the adapters to the null-modem cable to make a single cable with both ends having a USB male type-A connector.
Plug one adapter into the PC to create the /dev/ttyUSB0 device node. Treat this as the equivalent to /dev/ttyACM0 for your SoftwareModule.
Plug the other adapter into the PC to create the /dev/ttyUSB1 device node. Treat this as the equivalent to /dev/ttyGS0 for your emulated "hardware modem".
Develop, execute, and debug your emulated "hardware modem" on the Ubuntu PC host (without the unnecessary task of "creating a fake serial port").
Currently I want to create a qt application on my Desktop that say, has 3 buttons. These 3 buttons can change certain variables for my device, which will be connected to the desktop with a microcontroller.
I want my desktop application to be able to communicate with the microcontroller. For example, clicking a button might flip a certain boolean variable and the microcontroller will adjust accordingly.
I have no idea how to start and what sort of questions I should be asking and how to tackle this at a high level.
Thank you.
My desktop is a macbook pro retina 15-inch 2014 and my microcontroller is either an Teensy, or an Intel Atom.
I don't know what type of microcontroller you are using, but if it has support for UART you can use the QSerialPort lib (http://doc.qt.io/qt-5/qserialport.html) to send data using a serial port.
In case of an arduino, you can send messages using this lib directly via the USB emulated COM port. If it don't have USB emulated COM port, you should use a serial adapter (an Arduino board can play this role).
The first thing to look at is what communication buses are common between your desktop computer and your microcontroller. Does your microcontroller have USB or ethernet capabilities? Does your microcontroller have expansion boards for WiFi or bluetooth support? Do you have access to an I2C bus in your desktop PC?
Depending on the answers above, if your microcontroller and your computer do not share common communication buses, you might have to use intermediary hardware, for instance, you might want to use something like the FTDI USB (on your desktop) to UART (for the microcontroller) cables, you can find those here: http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm
In that case I'd recommend using a cable with VCD drivers, so the cable appears as a Serial port to your computer, which you can access in QT by using QSerialPort (http://doc.qt.io/qt-5/qserialport.html)
There would be other similar solutions, but I'd say that, if there are no shared buses between your microcontroller and host, this would be one of the most universal. Maybe if you specify your microcontroller or embedded board We could help a little more.
Hello i have an application built some times ago in C++.
It is used to control an appliance via serial port.
I remember the guy that developed it saying that his software is directly accessing the serial port (directly accessing the memory).
Since PCs with serial ports are becoming rare these days, would the software still directly access the serial port if i used a PCI extension serial port?
Thanks
That depends a bit on how much backward-compatible driver support your PCIe serial port has.
If it provides direct I/O-space mapping of a (possibly virtual) 16550 UART's registers, you will need to change the "base address" in the software but then it might work. If the drivers do not, then it's not going to work.
The first four standard serial ports have the following base addresses and interrupts associated with them:
| base IRQ
-----------------
COM1 | 0x3f8 IRQ4
COM2 | 0x2f8 IRQ3
COM3 | 0x3e8 n/a
COM4 | 0x2e8 n/a
The software should probably be rewritten to use more high-level access to the port.
I believe that the vast majority of local bus serial port cards emulate a 16x50 RS-232 UART. Unless you intend to use some special card, such as those expensive multiport cards used for managing modem banks, it would probably be fine.
USB/RS-232 converters are a different story altogether - in general they will not work with software that accesses the serial port directly, as their driver only provides access via the OS serial port subsystem. Even if their driver somehow manages to emulate a proper local bus UART, those converters often have different behavior w.r.t. signal timing that might lead to issues with software that does unusual things with the serial port. For example, I have had issues with attaching IR remote control receivers to some USB/RS-232 converters. Using a converter that supports USB 2.0 helps somewhat, but it is still far from the real thing.
You should also keep in mind that if your application is designed for an older OS, newer versions of that operating system might not allow direct access to serial ports anymore.
If all else fails, you might still be able to improve the situation by using a virtual machine. For example, VirtualBox allows the guest OS to access the host serial ports, emulating a 16550A UART. This might allow you to work around a driver or an OS that does not support or allow direct access to a serial port.
I searched around i found some PCI cards that map their serial ports to the memory.
I will try one of those.
Thank you all.
I have another solution.
PCs are coming with mostly usb ports.
so you can use any usb to serial port converter. it is very cheap and works fine.
I've got a strange problem with some code I inherited from another programmer who's left the company, and need some guidance on how to even begin to solve it.
The problem is this - on a semi-regular basis, we are finding that duplicate USB virtual comm ports are being created. For example, on my PC, when I view the Ports in Device Manager, and select "View Hidden Devices", I have two entries for the same device - one on COM6, and one on COM8.
Unfortunately, we cannot reliably re-create the problem. We suspect it may happen when someone quickly disconnects and reconnects the USB cable when our software is running, but that needs to be confirmed.
As far as I can tell, the code was written assuming that no one would ever unplug a cable. I see no logic whatsoever to detect this condition after the SW is started. And it fails when you re-plug the cable - silently generating read and write errors even after the cable is plugged back in. You have to restart the program before it will work again.
I have very little serial and USB experience, and am at a bit of a loss as to how to even get started on fixing this.
Can anyone suggest why this might be happening?
Misc. details, in case they might be relevant:
USB serial code is in a C++ DLL
VS2008
FTDIBUS USB/Serial drivers
Windows XP and Win7
Screen shot of duplicate Registry entries (note the value of the selected key!)
As explained on Raymond Chen's blog, the Old New Thing, here, and by commenters above:
https://blogs.msdn.com/b/oldnewthing/archive/2004/11/10/255047.aspx
To summarize:
Devices which are unplugged and plugged in again are tracked so they are not treated as a new device every time.
Usually this uses the device serial number to detect whether a device is the same one.
However not every device has a serial number. These devices are treated as the same device only if they have the same vendor ID and product ID and are plugged into the same port. If they are plugged into a different port they are treated as a different device.
Some manufacturers do not understand the word "Serial" in "Serial Number" and give all devices the same number instead of giving them numbers serially... To cope with this there is a registry setting which can be used to force these devices to be treated as if they have no serial number.
Therefore, if a device with no serial number or which is flagged in the Windows Registry as having duplicate serial numbers is plugged in to a serial port it has not been plugged into before, it will be treated as a new device rather than a reconnection of an old device. This will result in "Ghost" devices as you describe.
Some FTDI devices are specifically called out as having this problem by the manufacturer:
http://www.ftdichip.com/Support/Knowledgebase/index.html?ignorehardwareserialnumber.htm
Am trying to figure how can I make some software and USB hardware.
Let's put the hardware thing aside for now. For software, how can I send data to a USB port?
C++ / Java or any other language (prefer to be working on Linux).
USB ports are not like "dumb" RS-232 serial ports. It's a bus, that requires quite complicated handling, all driven by the host (the computer, typically). Very low-level operations such as "sending ones and zeros" to the data pins are more or less impossible.
The easiest way to program USB from user-space in Linux is probably to use libusb.
On the client (your custom USB hardware) end, either look for a system featuring a built-in USB controller, or a software stack. I don't think writing your own software stack is feasible, since you (no offense) don't seem to be quite at that level regarding your knowledge of USB.
V-USB is a software USB stack for Atmel's AVR microcontrollers, for instance.
As others have pointed out you have to write a driver for the USB device.
Another option is to communicate with the device using a serial protocol over USB, then your hardware needs an USB to serial chip. The best answer regarding USB over serial is in the question How to get C++ to perform I/O from a USB Port like a Serial Port by Mike DeSimone
If you want to bitbang I/O using USB, then you can connect a FTDI chip like the FT232 (which is used in many USB to serial cables) to the USB port.
On the PC you can use libFTDI to bitbang the I/O pins of the FTDI chip.
I think this is the easiest way for controlling I/O pins using USB.
An alternative to serial port emulation is USB HID (Human Input Device), which is supported on Linux out of the box. You'd use the "HIDAPI" to communicate with your device.
A usb port is just a serial port. Therefore, the first place that you want to look is writing a sofware to handle serial port communication.
Be aware that the OS may assign a different port number to the device whenever it's connected.