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.
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").
My development target is a Linux computer that has two physical serial ports located at /dev/ttyS0 and /dev/ttyS1. I also expect /dev/ttyS2 and /dev/ttyS3 to be defined.
Using stty -f /dev/ttyS0 and S1 reports the configuration of the two serial ports and reports something menaing "doesn't exist" for S2 and S3.
The hardware designers are talking about offering USB to Serial ports built onto the main board. They'll be DB9 connectors on the outside and just circuitry - no USB connectors on the inside. The number of USB-to-serial connections is not guaranteed and I know enough to design for "many" instead of one.
So, in setting up my port server daemon, I need to be able to determine which ttyS's and which ttyUSB's are "real" and which aren't. Will there ever be placeholdeer ttyUSB's? What if one were to be "unplugged" (say it was, indeed, a real USB coupler on the inside of the PC)?
Is there a better approach than popen()ing stty and examining its output to determine the status of the serial ports? Is there a C API for stty?
Thanks!
The "C-API" which stty uses is tcsetattr(3) and tcgetattr(3).
For finding TTYs without opening the device you may look at this question:
How to find all serial devices (ttyS, ttyUSB, ..) on Linux without opening them?
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.
Is it possible to read/write from/to a specific USB port, avoiding all that USB handshaking stuff?
What I want to do is communicate with a microcontroller, for example, that doesn't have a USB driver on board via USB. I want my C++ application to be able to send data via a specific USB port and then to receive data from that same USB port.
Basically what I want to be able to do is treat that USB port like a serial port. Is this possible? Is there a workaround I can use?
Thanks in advance.
PS: I know this isn't the best way to go about communication with a uC, but let's assume, for some reason, I have to do it this way.
Edit: BTW I'm using Windows 7
The usual solution is to use an FTDI USB-to-serial chip, such as the FT232R, on your microcontroller board. Then, as far as your MCU is concerned, it's talking to a serial port, and on the host machine you just have to have the right drivers.
On my Mac, the FTDI chip shows up as a serial port at /dev/tty.usbmodem____, where ____ is some persistent unique ID assigned by the Mac on first detection. Unplugging and replugging, even weeks later, gets the same number, but it's a different number on a different Mac.
On Windows, it shows up as a new COM port if you have the drivers installed, IIRC. On Linux, it shows up as /dev/ttyUSB_ where _ is a serial number starting at 0, if you have FTDI serial driver support enabled in the kernel. This can get tricky if you plug in more than one FTDI chip.
If your microcontroller has a built-in USB port, then you need to find the software for it to identify itself as a standard CDC (Communication Device Class) serial port device (standard documentation available). Most OSs have support for this standard USB device class.
Use one of the USB to serial port adapters. The USB port will look just like a serial port to your C++ program.
In general you can do a close approximation of this using the HID interface: drivers are built in, and you can send feature reports in both directions. It isn't quite serial port simplicity (since it is packets, as opposed to a continuous byte stream) but hidapi makes it really simple and cross-platform.
I am new to hardware programming(especially USB) so please bear with me and my questions. I am using C++ and I need to send/receive some data (a byte array) to/from a USB port on a microprocessor board.
Now, I have done some serial port programming before and I know that for a serial port you have to open a port, setup, perform i/o and finally close the port. I am guessing to use a USB port, it is not as simple as what I mentioned above.
I do know that I want to use Microsoft standard drivers and implement standard Windows IO commands to accomplish this, since I believe there are no drivers for the microprocessor board for me to interact with.
If somebody can point me in the right direction as to the steps needed to "talk" to a USB port (open, setup, i/o) via standard Windows IO commands, I would truly and greatly appreciate it. Thanks you so much!!
USB in a nutshell is excellent background reading.
For a generic USB module try LibUSB which includes some examples of talking to standard devices. LibUSB-Win32 is the windows port of that library.
You're right though, it's nowhere near as simple as an RS232 port.
What microprocessor are you using? Does it come with any USB hardware or are you thinking of trying to implement it all in software (not something I'd recommend even contemplating!). A lot of microprocessors come with code samples which can emulate simple HID USB devices like keyboards / mice etc. which you can use as a starting point. Failing that, there's probably a few off-the-shelf options which will save you a lot of headaches :-)
Find out the USB chipset used on the microprocessor board, e.g. Ftdi, Cypress, etc. These manufacturers supply drivers, libraries and example programs for the comms, this is the easiest way.
There are no 'standard' drivers as such unless your board is set up as an HID device, however if you are using Windows, Microsoft supply a WinUSB.sys 'generic' driver which may or may not meet your needs (it doesn't support Isochronous transfers).
Should you write a driver for the USB device that will attach itself. If you know the type of chip that has the USB i/o on the board, the driver will be for that device.
There may already be driver's for that chip if it is an STM or there may be an API to help develop drivers for it. It would probably be a custom device but you should look through device types to see if there is an existing type that matches your device. If so there may also be a driver already for it which you can use. Information about the board is necessary.
WRITE YOUR OWN DRIVER
With out getting too far into it, you should learn Microsoft's driver model, the difference between user mode and kernal mode drivers, what driver node's represent, driver hierarchy and how they logically attach themselves, different types of drivers (filter, function, bus), how kernal driver's communicate with user interface, dynamic link libraries, frameworks and API's, WDM framework/API, KMDF and UMDF API's and this is just a short list.
OR you can use an existing driver.
USE USB MICROCONTROLLER SUPPLIED DRIVER
We do not know what firmware the USB microcontroller is using, if any. If there is no firmware (if say the chip came with out it or relies on eprom to store it and not flash) then if we knew if the chip supports usb bootloader, you can flash it or load it's firmware through the USB and there is no need for JTAG or other peripherials. Likely the usb alone is capable of getting you off the ground and anywhere from there. Typically these types of questions arise when considering board's with out a USB microcontroller.
Here is a link to a slighly related driver. Most USB microcontrollers serve the purpose of switching USB communication to UART as most microconrollers that actually do the thinking and control everything are not equiped with USB i/o but instead UART or some other i/o pins like I2C or SPI etc..
https://www.silabs.com/products/mcu/Pages/USBXpress.aspx
That driver may actually work, if not something similar but for the manufacturer of your USB microcontroller; will almost certainly do the job. Hope this helps.
By hardware programming, do you mean you will be programming the microcontroller? If so, there is no way you will use "standard windows drivers" or anything like that.
The USB standard is very thick. Check it out here
It is a very involved topic and I recommend finding USB implementations already created for your microcontroller. (which we may be able to find if you gave us more info)
What kind of microprocessor and what kind of board?
Many processors come with support for USB ports. Also, some hardware boards come with USB contollers too.
For example, the processor that my shop is using comes with two USB controllers that can act as a hub or as a device. We're even adding another processor to act as a USB controller.