MSDOS API serial port only reading last sent character - serial-port

I've been playing with the MSDOS API in assembler for some time and I'm trying to build an application to read/write from the serial port. I'm currently using VMware Workstation 11 + VSPE (http://www.eterlogic.com/Products.VSPE.html) to emulate the serial port communication.
One thing I noticed is that if I send let's say "asdfgh" into the serial port and then read it in MSDOS (Using interrupt 21h function 03h, but I also tried interrupt 14h function 02h), it only returns the last character read: "h"
According to some documentation I read, if an application sends data faster than I can process it, characters will be lost, which means that either there is another way to make MSDOS save bytes to a buffer (controlling flow) or I have to write a driver that does this (or maybe a TSR program that manages this I dunno).
So the question is, do I have to write a driver or is there another way to do this?

I managed to write a program that turns on the 16550 FIFO buffer and now It works using the DOS API.
So it was just the FIFO buffer
No need to slow down the baud rate or whatsoever. Nonetheless, if one happen to have a 8250 it's probably either that or implement a communications driver on top of it
Also, this helped a lot:
https://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming#UART_Registers

Related

How does a kernel driver talk with another device?

I have an FPGA board with unix-based firmware. I need write out the program to run on this firmware that will send commands to some devices via I2C bus and will receive responses. I use for this special character file in Unix that i map in my program and write to it special commands & read from it responses. Each memory area in this mapped memory corresponds specific register of the FPGA which specified in Unix-based firmware (as i understand).
So, the question is the next one. As i understand, when i write some command to that mapped memory region of the special character file the kernel calls certain driver to handle bytes that I've written and send them through I2C bus (for example). Am I right? If so, is there some guarantee that the response from that device will be buffered and I will be able to read it from the mapped region in any time? Or does it depend on implementation specific driver?
I'm sorry if question is not clear some way, I am a newbie in this stuff.

Multi-drop bus to rs232 Convert

I have a project using MDB (multi-drop bus) for vending machine (VDM).
The VDM has a MDB-RS232.
I'm not sure if it converts 9bit - 8bit (MDB-UART).
How do I read data from VDM in my computer?
Thanks all
MDB (multi-drop bus) is 9 bit, because after the standard 8 data bits (like in standard RS232 UART communication) there is a 9th bit called "mode".
(Wikipedia on MDB: "the mode bit differentiates between ADDRESS and DATA bytes.")
But you can read such data even with regular 8-bit RS232 interfaces, e.g. a plain standard USB-to-RS232 device for PC.
Here is how:
Use 9600 baud, 8 data bits, 1 stop bit, but RS232 parity setting "Space". Make sure you receive the original character value even in case of a Parity Error indication. Any MDB address byte from your VDM will be received with a Parity Error (but still be displayed correctly). Any data byte will be displayed without error.
For sending MDB ADDRESS and DATA bytes using a standard 8-bit RS232 port, you could apply temporary parity changes: Change the parity setting to "Mark" before sending an address byte, then change back to "Space" before sending data bytes.
On Windows, you can do such tricks with our Docklight software (see Docklight and MDB). It's free for basic testing and there is also a related 9-bit example project.
On Linux / Raspberry Pi other users have successfully implemented the parity trick, too, see this stackexchange post about a MDB + Pi.
But also with RealTerm, Teraterm, Termite, Bray, YAT or any other RS232 application you should be able to read the data, as long as it handles "Space" or "Mark" parity settings correctly.
You'll need an adapter which will do all convert operations on-the-fly and in real time. If you want to emulate VMC (master), you'll need MDB-UART master adapter. If you want to emulate MDB peripheral device (such as coin changer, bill validator etc), you'll need this. For two-way "sniffing" MDB bus you'll need a combination of these devices.
Direct connection PC's RS-232 to MDB will not work due to strict MDB timings (delay between VMC command and peripheral response must not exceed 5ms, delays between POLL requests are 50-300ms in general). I mean pretty reliable functioning available for commercial purposes.

Upload hex using USB CDC from microcontroller as host

So has anyone done this?
I'd like to store a hex file on an SD card and just blast it to any boards I have with the catarina bootloader on them when I connect to my uploader device.
This seems to be the correct protocol to talk to the catarina bootloader (the command definitions are at the end.) http://www.atmel.com/images/doc1644.pdf
If I manually force it into programming mode from COM4 by setting it to 1200 baud and closing the port, then opening COM5 and sending it one of the commands I do get a response as I would expect but even if I put it in programming mode by sending "P" it dropps back out after a second or two and doesn't stay in programming mode as I would expect.
It seems that the timeout gets reset/extended if certain commands are sent so I guess that makes sense.

linux serial ports -- mulithread program

I am working on a smartcard reader project here i will have to read/write data from the smartcard reader.
Also i will have to read/write data from PC application.
There are two serial port on my microcontroller one connected to smartcard reader other to PC.
Smartcard reader <------> Microcontroller <-----> PC
I have ported linux & using /ttys0 & /ttys1 driver for this.
1> My question is if application have to find that some data is available to be read from the port than will i have to always check it with read() system call ?
2> Does ttys0 driver have internal buffer to store received data ? Or data is lost if application do not read data immediately ?
3> Here using seprate threads for rx/tx from each port, is it right approach ?
Please guide me i am new to Embedded linux.
//John
Yes, there's a fair amount of buffering on linux tty's.
You have a few choices for how to interact with them.
you can make them non-blocking, and frequently poll to see if you can read data from them (but this may result in uselessly spinning CPU cycles, slowing other tasks)
you can use select() to yield to the scheduler until one of your devices has data for you to act on
you can use blocking I/O, however since you have multiple ports that may also require multiple threads
TTY programming is similar to socket programming in Linux. So basically you can set the socket to be a asynchronous and receive a signal once data is available. Regarding buffering, yes it's buffered using two flipping buffers. You can check chapter 18 in Linux device drivers 3rd edition regarding TTY implementation in the kernel.

Hyper-V: Connecting VMs through named pipe loses data

We are trying to connect two Hyper-V VMs through a serial port. Hyper-V exposes the serial port as a named pipe to the host system, and implements the server end of the named pipe. Consequentially, to connect them, we need to write a named-pipe client which connects to both VMs, and copies the data back and forth.
We have written such an application. Unfortunately, this application loses data.
If we connect two hyperterms, and have them exchange data, the transmission sometimes succeeds, but in many cases, the receiving end reports errors, or the transmission just deadlocks. Likewise, if we use the link to run a kernel debugger, it also seems to hang often.
What could be the cause of the data loss? What precautions must be taken when connecting named pipes in such a manner?
Edit: We have worked around the problem, using kdsrv.exe. The COM port of the debuggee continues to be exposed through a named pipe, however, the debugger end talks to kdserv via TCP.
The data loss is not due to the named pipes. It is infact the COM ports (emulated and physical) that may lose data since they operate with a small buffer in the UART.
The named pipe receives all the data that is written to the COM port. Your program reads data from the named pipe and writes it to another named pipe. This is where data loss can originate if you write too fast the receiveing COM port's UART can overflow leading to data loss.
You may need to add some delay to avoid exceeding the baud rate expected by the receiving side.
In addition, you are missing ResetEvent() calls in your program.
For your KD issues, you may need to add resets=0 to the connection string.
I did not try to connect VM via Serial but I connected VM and Host via usb (through network)
and it works.
If it is required for your software to establish serial connection try to test via serial emulators with work through tcp\ip.
I think John's suggestion is correct - if u are using a slow CPU to emulate TWO VM, then the guest OS's drivers for serial port is highly drifted away from the high speed version. So John's suggestion is to set the input/output side of the serial link to the slowest possible speed. Ie, you cannot use high baud rate for the inter-VM serial communication. Instead u have to use the slowest possible speed, and so that the VM guest driver will take that cue and use the slower version of the driver. But your physical machine must have sufficient CPU speed to run two VM concurrently, to avoid the "emulation drift" of the the serial driver.
Well, just my guess, but there is a VirtualBox version of your problem, seemingly no issues running it:
http://bodocsi.net/2011/02/how-setup-serial-port-link-in-virtualbox-between-two-guest-virtual-machine-in-linux/
But the following bug ticket for VirtualBox does describe many similarities to your problem:
https://www.virtualbox.org/ticket/1548
And reading the end seemingly indicate the solution has to do with VirtualBox's internal source code. Perhaps it is Hyper-V's problem?

Resources