Custom ethernet driver problem - linux

I dont know if this questions is relevant here or superuser, but ask anyway.
I have below mentioned setup- A Linux Desktop PC system. To this is connected one custom FPGA development board.In this FPGA there is an Ethernet Network Card IP realized and executing. This board is connected to the FPGA development board using USB ports-USB cable, and Serial cable. Essentially this whole setup tests the FPGA based Network card and the associated ethernet drivers realized thereon.
There are many applications which run on the host linux pc and send the data to the FPGA based Ethernet n/w card, which accepts it, does the necessary processing and sends to the physical layer realized on the FPGA which then sends it out over the ethernet network to some other node/device on the network.
This setup works fine, even when multiple applications from the host-pc send data to the FPGA network card. As one of the applications, i use a Linux based VLC player(its a multimedia player) to play some multimedia streams from the Linux-host and that data is sent to the FPGA network card. In the VLC player, i seek (reverse/ forward) the stream using the vlc player controls. When i do this seek operation continuously, it makes the linux host pc. hang/freeze. No i/o device work, only reboot works.
Now i tried to see the logs in the linux host pc /var/log (dmesg) to see if i get a clue about what process/application caused the freeze, but i could not get any input from it.
How do i proceed to isolate different components(Software , Hardware, ) involved in this whole setup of mine to narrow on the problem root cause?
Is there any way to communicate to the frozen linux-host via some means(Serial cable or some other connection to get any data from it when it hangs?
What steps i should follow? How can i tell if the VLC application is a problem or the FPGA network card driver is a problem, or the something else ?
Any pointers will be useful.
Thanks.
-AD.

You mention that the Linux host is frozen. I would first determine if it is actually locked up in the kernel or if there is some user space process(es) consuming too much CPU.
Can the host be pinged (preferably on an interface separate from your FPGA Ethernet card)? If it replies, the kernel is not locked up.
Hardware Problem?
If possible, can the setup be temporarily changed to remove the FPGA Ethernet card and then reproduce the problem? I would do this to help isolate issues specifically related to the hardware (FPGA Ethernet).
User Space (Software) Problem?
If you remove VLC from the equation, can you still get the lockup/hang to happen by using another method to generate Ethernet traffic?
You might try creating a shell that runs at a higher priority in order to retrieve data when the system seems to hang. Perhaps by running top in this high priority shell you can determine who, if anyone, is using all the CPU. You can run this shell over the network (telnet/ssh) or via a serial terminal.
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
struct sched_param scheduling_parameters;
scheduling_parameters.sched_priority = 10;
if (sched_setscheduler(getpid(), SCHED_FIFO, &scheduling_parameters) < 0) {
printf("error is %d\n", errno);
}
execlp("/bin/bash", "bash",0, 0, 0, 0);
return 0;
}
Kernel (Software) Problem?
You can enable the magic sysrq key and examine the system state and go from there. Kernel developers use this interface to debug their software. The CONFIG_MAGIC_SYSRQ option has to be enabled at kernel compile time in order to use this functionality.
After empirically narrowing a bug down to a specific module, printk() is still a good resource.
It may also be helpful to enable the kernel debugger (KDB) and connect to it via a serial cable.

#Jscheimer: thanks for a detailed pointers on my problem. After lot of debugging & some discussions with other system developers at work place, i finally found the root cause. There is a DMA peripheral which comes into picture in this whole setup. The DMA was comfigured for aligned access, but somewhere in some data transfer it was receiving a unaligned address, as a result of not checking the buffer alignment by me in the code, which was causing the hang/freeze. And there was no pattern to this behaviour.

Related

How can I check if the FPGA device is connected to the server?

For some reason, I can only remotely control a server containing FPGA (Intel Arria 10 GX FPGA). But when I use the command in Intel OpenCL for FPGA to find the driver, I cannot find the FPGA device that can be used.
The command is as follows:
aocl diagnose
Output result:
enter image description here
Later, I used hardinfo to check whether FPGA is included, but unfortunately there is no useful information.
The only thing related to FPGA is that I found two files about fpga under my server (Ubuntu16.04). Since I am using FPGA for the first time, I don't know what this file represents.
enter image description here
In addition, due to network problems, I have not yet been able to install OPAE for testing. I would like to ask if there is an easy way to verify whether the FPGA is successfully inserted into the server.
You can check with lspci | grep "FPGA". The lspci command lists all devices connected to a PCIe slot, whether a driver is installed or not. If you find the FPGA in the list of devices, it is installed in the PCIe slot on the mainboard.

How does the Linux Operating System understand the underlying hardware?

I want to learn how Linux OS understands the underlying hardware.Can anyone suggest me where to start for getting this understanding,As of now i just know the '/dev' sub-directory plays a vital role in that.
It has the device special files which are like a portal to the device driver which then takes it to the physical device.
I read somewhere that Udev daemon listens to the netlink socket to collect this information and Udev device manager detects addition and removal of devices as they occur.
But with these i am just not satisfied with the thought of how Linux reads the hardware.
Please let me know where to start to understand this, i am so thankful to anyone trying to help.
I think at first you need to find out how the memory mapping works. What is the address space and how it relates to physical memory. Then you could read about how the hardware is mapped in address space and how to access it. It is a big amount of docs to read.
Some of those information are in Linux Documentation Project.
Additionally some knowledge about electronic would be helpful.
In general - Linux for communication with devices needs some "channel" of communication. This channel may be for example ISA, PCI, USB, etc bus. For example PCI devices are memory mapped devices and Linux kernel communicates with them via memory accesses. So first Linux needs to see given device in some memory area and then it is able to configure this device and do some communication with it.
In case of USB devices it is a little bit complicated because USB devices are not memory mapped. You need to configure USB host first to be able to communicate with USB devices. Every communication with USB device is achieved via USB host.
There are also devices which are not connected via ISA, PCI or USB. They are connected directly to the processor and visible under some memory address. This solution is usually implemented in embedded devices. For example ARM processors use this approach.
Regarding udev - it is user-space application which listens for events from Linux kernel and helps other applications with recognizing device addition and configuration.

C++ Detecting USB serial device plugged/unplugged

I need to detect when a USB serial device is plugged or unplugged on my embedded system and know what is the tty associated with it.
My system runs over a 2.6 Linux Kernel.
Since I don't have write access to udev rules, nowadays I'm trying to get this information from the file system, looking for modifications in /sys/bus/usb/devices directory. However, I'm facing some problems with this approach.
I know what is the Id BUS of the USB port connected (e.g 1-1.3). So, I search for the associated tty (looking for a directory in /sys/bus/usb/devices/<Id BUS>:1.0/tty/ - e.g. /sys/bus/usb/devices/1-1.3:1.0/tty/ttyACM0). This way I know that I should use /dev/ttyACM0 to communicate with my device.
But, sometimes, this device (/dev/ttyACM0) does not exist.
Is there any better way to get this information?
I even thought trying to get this information from the syslog, but I don't know whether this is a pretty good idea.
Edit:
Only to clarify, my system needs to be able to detect state changes in the USB bus, i.e. detecting when a new device is plugged (and getting the tty name linked to it) or an existing one is unplugged.
The system is monitoring up to N USB/serial devices, which are plugged to it using an USB HUB. During its normal execution new devices can be plugged, existing devices can be removed (or rebooted by a remote command - out of this scope). When a device is rebooted, it could receive a different tty from the previous one used before (e.g. ttyACM0 -> ttyACM3), since the kernel designates to it a tty which is free at the moment, and it is a big problem to me.
Netlink is the preferred mechanism for communication between kernel and userspace.
You would create a Netlink socket with family NETLINK_KOBJECT_UEVENT, listen on that socket and filter out messages that contain SUBSYSTEM=usb and ACTION=add for USB plug events or ACTION=remove for USB unplug events.
I wrote a USB abstraction library called libusbp. You should look at its port_name example, which shows how to use libusbp to get the serial port name (e.g. /dev/ttyACM0) for a USB serial device. Behind the scenes, libusbp gets this information using libudev.
Check if the virtual file is deleted using stat.
#include <sys/statvfs.h>
...
struct stat sb;
return (stat("/dev/ttyUSB0", &sb) == 0); // true if open, false otherwise

Sniffing IOCTL and serial port communication

I'm trying to reverse the protocol used by an early nineties logic analyzer an its PC software.
The device is connected via RS-232 (propietary wiring) and communicates with a DOS program, successfully running on DOSBOX.
I'm able to control the device with the original software but it would be useful to autimathe the downloading of data from the analyzer using a custom program but to do so I need to know what is going on the serial port.
Ineed to know what mode is the serial port set, while I know for sure the datarate is either 1200 or 9600 bps (configurable on the device) I don't know the flow control (I guess it is RTS/CTS).
I also need to tap into the conversation between the prgram and the device without disturbing their communication.
Reading the serial port with another program (cutecom/minicom) prevents the emulator from receiving the data from the hardware.
So, summing up, what I need to know is:
What configuration is set on /dev/ttyS0 (via IOCTL calls, i think)
What goes on between program and device.
I was thinking in programming a library which acts as a proxy for the standard c library (via LD_PRELOAD) but there must be an easier way to do this.
You can use slsnif (Serial Line SNIFfer).
http://linux.die.net/man/1/slsnif
Here's a link to the sourceforge project so you can download it. I don't believe it comes with any modern distributions but I could be wrong so check your distro's software repository first.
http://sourceforge.net/projects/slsnif/
I use ttyrpld for tty sniffing. I ported it to PPC and run it on 2.6.32. It logs all of the tty traffic on the board to files, one per tty. Works well.

Controlling a parallel port via USB adaptor on modern hardware and OS

I have a USB to parallel port device that i want to interface with through c++ on a modern windows OS (xp and newer).
I've done a little research but the information is a bit patchy when it comes to programming to one of these USB to parallel port devices (most of the information is dated and assumes that you have a parallel port built right into the motherboard, something my brand new computer doesn't have). One reference even says that it is not possible to interface with a USB to parallel port from a C++ program without some sort of software changes.
All i want to do is to is be able to read or write 8 bits to the parallel port through a USB to parallel port device on a modern computer running a modern windows OS (with ports being dedicated to reading or writing only).
Is there any quick and easy way of doing this? Some sample code would be greatly appreciated.
Also, how many of these USB to parallel ports can I interface with my computer? Am i limited to 3 due to some sort of legacy addressing or can i have as many as my USB and CPU are able to support?
Working off VC++ 2008, running Windows 7 x64 with a Core i7 860.
Edit: a bit more information...
I've tried using inpout23 along with some prewritten test program. It compiled just fine and ran just fine claiming to have both read and written to a parallel port. I had my USB to parallel port connected to the computer and that port connected to a cable in which i had identified, stripped and soldered each of the 25 wires onto a sort of plug for quickly plugging into a breadboard for testing. None of the output pins had changed to what the program had said was written to them (instead they were all set to high and never changed).
I've done this in the past and I have good news and bad news.
The good news is that it always worked (sometimes with tweaking), which is a tribute to the electronic manufacturers of designing extremely robust protocols. Apparently the USB to parallel converters all provided the hardware port emulation.
The bad news is that performance was awful on the 'bitbanging' interface models. If you do not mind slow updates this is not an issue at all. I used it for programming uControllers and soon the price of serial or USB programmers was overcome by my impatience.
Just use the windows API to read/write the LPT or COM ports and it works (slowly).
I've worked with a USB-to-serial port adapter before and I guess USB-to-parallel should be the same. You should have got a driver along with the adapter - this does most of the work for you, hiding the USB interface and presenting it to the OS as a traditional parallel port. For example, when I plug my adapter into the USB port, it just shows up as COM4 in Device Manager. I'm guessing yours will show up as LPT1 or something. From there on, it's a matter of using the standard Windows API to access these ports. (see Communications Resources on MSDN)
Misteriously I succeed with the USB to LPT-DB25 Wire bought in ebay.com.
We should connect a LED between the /LF Line Feed and GND pins.
After discard the USB registers in order to find that one associated to the USB Cable, we should build an API (Application Programming Interface) to interact with the outputs/Registers.
I'm going to try to attach a picture to have a look how I managed it:

Resources