How does serial console communication work in a microcontroller? - c

My doubt is regarding the physical layer of the communication, I know from practice that for using for example teraterm to communicate with a MCU is simply enabling and configuring an UART peripheral, and then connect via USB the microcontroller and voila.
But it doesnt make sense to me yet that if USB connects to DN and DP, and an UART uses RX and TX, how does the host effectively communicates to the microcontroller?

There are two possibilities.
You connect to a USB/UART bridge such as devices made by FTDI or Prolific,
The microcontroller has a USB device controller and USB stack implementing the CDC/ACM device class (virtual COM port).
In the first instance, the bridge chip presents the CDC/ACM device to the host and exchanges data with a UART connected to the microcontroller UART. I/O control such as setting the baud rate have no impact on the USB connection, rather they are used to configure the UART link.
In the bridge arrangement, the bridge chip may be on the micro board, or it may be in a USB/serial adapter cable. Moreover internally the bridge chip is a microcontroller with a CDC/ACM device stack.
Unlike say RS-232, USB is not a peer-to-peer full duplex connection, and is not merely an electrical connection; USB requires quite complex device and host controllers and is more analogous to a device bus such as PCI than it is to UART serial connections. A CDC/ACM class device conforms to a specific protocol to allow a "virtual" UART to appear at the host. The UART you see at the PC is emulated, and is not physically the UART in the bridge.
The physical actual USB connection is a master-slave connection, with data and I/O control commands (such as baud rate and flow control) sent in USB packets to be unpacked, interpreted and transferred to the application layer via the CDC/ACM USB stack. In this arrangement the device, acting as a slave cannot initiate an exchange; rather the host continuously polls the device to which the device may return a packet containing its "tx" data. The polling and data rate of USB are fast enough to allow the simplex master-slave exchange to emulate a full-duplex UART connection, at higher throughput than can normally be achieved by a typical real UART, and certainly faster than a physical RS-xxx connection.
You can get an idea of how all this works by observing the raw USB data exchange using a tool such as WireShark. You will see that a lot more than just your application "serial" data is being exchanged.

You need to use a uart-usb interface IC that can convert uart to usb (and vice versa).

Related

Microcontroller not recognized at USB port when connected via pins

Im having issues with my TI LAUNCHXL-F28379D. I have it connected to the laptop I am trying to send data to/from via pins P19 (SCIBRxD) and P18 (SCIBTxD), as well as GND and 5V via J16, using a USB Type B cord to which I sautered pin connectors. I'm sure power is being supplied to the board as when I plug the 5V cable of the USB cable, the RGB lights and 3 other small ones turn on. However, the Computer does not recognize ithe controller at the port - it only recognizes if if it is connected via the board's Mini-USB port. I've also written a C Program which opens the COM port and reads data - but this does not work without my knowledge of the COM port number, usually found in Device Manager. I cannot get any further in my project without the port number and it is very annoying. I will attempt to resauter a new USB cable, but if there are any other possible solutions, or if I'm doing something wrong, please let me know.
Absolutely all feedback is appreciated!
The SCIBRxD and SCIBTxD pins belong to the SCI peripheral in the microcontroller. This peripheral implements a UART port (a.k.a. COM port, a.k.a. TTL serial port). It is not a USB port. Nothing useful will happen if you connect it to a USB port, because it is not compatible with USB in any way.
USB-to-UART adapters (a.k.a. USB-to-serial adapters) do exist. There is one built into the LaunchPad. The UART side of the adapter is connected to the SCIB pins, and the USB side of the adapter is connected to the USB port.

Linux C USB write speed

I am using a Raspberry Pi in order to communicate with a GSM/GPRS modem by USB. I am able to communicate in 115200bps. I would like to improve the communication speed as much as possible but I do not know how I should do it. The connection is RPi's USB <--> Modem's USB
I am programming in C and I have to choose the speed_t in cfsetispeed and cfsetospeed functions, which it`s maximum is B230400... I am using write function to send data.
USB 2.0 protocol has theoretically some mb/s speed so, how could I achieve this?
Unfortunately you can not achieve higher rates.
Most of GSM/GPRS modem have inbuilt USB-->Serial(RS232) Converter.
The USB port is just for USB connector compatibility.
To communicate to these modem's from any computer you need to install drivers to Emulate a RS232 connection.
In this case your board is already have those.
So basically you are doing a RS232 communication over USB lines. Your speed will be limited by RS232 standard baud-rates.

Linux Serial Device Server over USB?

I have an embedded Linux solution and want to create a command service over serial USB. The idea being that when a computer connects to my embedded via USB, they see a serial device and send serial commands to me through that port and I send responses back.
I need some help in the direction to proceed. Do I need to emulate a serial device so they see me as a COM port? Is there build in Linux solutions to broadcast my details as a serial device? Are there code examples? I can see block devices connect with my embedded solution like a USB storage device. When I plug into another computer, I would like it to see me as a serial COM port.
I just need help in the direction of which path I should go down to solve this.
Thanks in advance.
What you are looking for is the Linux USB serial gadget. The Linux USB gadgets framework allows devices to behave as a variety of standard USB devices, including serial devices, Ethernet adapters, and mass storage devices.
Note that USB gadgets will only work on targets with a USB controller that can be set to operate as a USB device. Not all USB controllers and target devices are compatible with this configuration. For instance, most PCs have a host-only USB controller, and the Raspberry Pi Model B is not compatible with gadgets because it contains an embedded USB hub upstream of the USB ports. (However, the Pi Zero is fully compatible with gadgets.)

How to implement an ethernet modem

Okay, what I want to do, as a training exercise, is to implement something like this
client --ethernet--> Modem1 --GPIO--> Modem2 --ethernet--> My Home Router
Where the client connects to Modem1 using an ethernet cable.
Modem1 is a Raberry PI, converting the signal and relaying it via the GPIO
Modem2 is a Raberry PI, receives the data from the GPIO, and send it via the ethernet cable to my home router
I want to implement the Modems, but have little idea where to start.
I have read up a little on ethernet programming, but still can't find answers to the "simple stuff" like.
How do I implement Modem1 so that when its connected to the client, the client discovers it as an internet connection.
On the Modem2 end, how do I make "My Home Router" send packets meant for the "client" to Modem2, so that Modem2 may forward them.
and possibly things I haven't though of....
So, how, concretely, can I implement this? preferably in c.
I'd venture to say you might be able to write some sort of custom GPIO intermediate layer.
Read Ethernet->Encapsulate->Write GPIO->|->Read GPIO->Decapsulate->Write Ethernet
(and vice versa)
The problem then becomes: How can both modems act as "Ethernet proxies"?
Modem1 acts as a proxy for the router. Modem2 acts as a proxy for the client. If your Raspberry Pi can spoof MAC addresses, you might be able to fool Ethernet peers into communicating with your modems' Ethernet port. The reason why you need to spoof MAC addresses is that in TCP/IP networking, there is the ARP table, which maps remote IP addresses to the MAC address that can route IP packets to/from them. This is what allows your client to communicate to your router over TCP/IP.
Another potential pitfall is where your modem communication introduces delays that interfere with the Ethernet layer's handling of the protocol. For example, the Ethernet protocol may have real-time constraints that could be shattered if you introduce delays...
But let's assume anything is possible in a perfect world...
You'll need to write code for reading/writing Ethernet messages (I've seen open source code for reading/writing Ethernet packets over raw sockets in Linux)
You'll need to write a custom driver for your GPIO comms.
This means implementing a carefully thought-out protocol to manage pins state, start-of-message, end-of-message, data-payload, checksum, whatever...
Finally, you'll need to write a top-level communications layer that implements:
Ethernet-to-GPIO process:
a) read from Ethernet port, encapsulates Ethernet packet into a custom message (or message fragments)
b) communicate this custom message, using your custom GPIO protocol driver, to the external GPIO peer
GPIO-to-Ethernet process:
a) Read from GPIO, using your custom driver code
b) Decapsulate Ethernet packet
c) Write Ethernet packet to Ethernet port.
these two processes run forever...
Again, all hinges on whether or not your modems can insert themselves in an peer-to-peer connection without disturbing the natural flow of the Ethernet protocol...
As for the 'C' part...
If you use open source libraries (or code snippets) for reading/writing raw Ethernet via raw sockets, that is most likely written in C.
Your GPIO code will read write from the GPIO pins in one of two ways: from a memory mapped H/W address, or using ioport calls on that H/W address.
Receive raw Ethernet frames in Linux
Send a raw Ethernet frame in Linux
Good luck

DMA transfer to a slave PCI device in Linux

I am a bit confused regarding DMA transfers with a PCIe device.
Say, for example, I have a slave PCIe device, and I want to transfer a block of data from the device to the RAM, using a DMA transaction. Note that the device is slave, and does not have a DMA "machine" on it.
I know I need to obtain a DMA-able buffer in RAM (either by allocating a coherent one, or by mapping a page) first.
But what's next? what's the API to start a DMA transfer of N bytes from address S to address D?
Can modern systems issue a DMA transfer to/from a slave pci device? if so, what is the Linux API for that?
As explained here:
[ISA]
In the original IBM PC, there was only one Intel 8237 DMA controller [...]
A PCI architecture has no central DMA controller, unlike ISA. Instead, any PCI component can request control of the bus ("become the bus master") and request to read from and write to system memory
The PCI bus does not have a "central" DMA controller - instead, each device can be a DMA "controller".
First of all, there are no slaves and slave holders inside modern PC. There is south bridge (in PCI) or Root Complex (root of PCI-express device tree) and there are some other PCI/PCIe actors, like bridges, soldered chips, plugged cards, hardware debuggers etc. I'll assume that you are asking about plugged card or some other peripheral device, like soldered Sound Card or Ethernet chip.
According to this detailed description of "Transaction Layer Packet" (TLP, "PCIe’s uppermost layer"), there is "Bus Mastership (DMA)":
On PCIe, it’s significantly less exotic. ... anyone on the bus can send read and write TLPs on the bus, exactly like the Root Complex. This allows the peripheral to access the CPU’s memory directly (DMA) or exchange TLPs with peer peripherals (to the extent that the switching entities support that).
Also, there is some benefits of DMA capability from plugged devices: DMA attack. And PCIe is listed as capable of initiating DMA transfer:
Systems may be vulnerable to a DMA attack by an external device if they have a FireWire, ExpressCard, Thunderbolt, or other expansion port that, like PCI and PCI-Express in general, hooks up attached devices directly to the physical address space.
I think, there is no universal API for programming DMA transfers that are initiated from the peripheral device itself. This depends on the what the device is, when the DMA should be started and what will be sent.

Resources