UP RUNNING NIC prevents the communication of another UP RUNNING NIC - udp

I have a VxWorks machine with 4 different Gigabit Ethernet Interface (GEI). My program on this machine (computer0) communicates with two different machines using these GEIs (gei0 -> computer1 and gei3 -> computer2). The connection between computer0 and computer2 should be changeable. I want to terminate or reinitiate the connection between them according to the flow of the program. To do this, I am using ifconfig("gei3 up") and ifconfig("gei3 down"). Although I can terminate the connection whenever I bring the gei3 down, I cannot reinitiate the connection with ifconfig(gei3 up). Using ifconfig(), I make sure the specified interface is up/down. Although the gei3 is UP RUNNING and I am able to ping computer2 from computer0, there is no successfully delivered message to computer2. I checked to result of sendto() function and it does not throw any error.
Interestingly, whenever I bring the gei2 down, the communication between computer0 and computer2 is established. However, when gei2 is up, I cannot reinitiate the communication using ifconfig(gei3 up). I wonder what makes gei2 avoid the communication of gei3.
These are further details about the problem.
I am using the following commands to attach and up gei3 and gei0
respectively:
ipAttach(0, "gei") // 0 for gei0 and 3 for gei3
ifAddrSet("gei0", "ip0") // 0 for gei0 and 3 for gei3
ifMaskSet("gei0", 0xff000000) // 0 for gei0 and 3 for gei3
ifconfig("gei0 up") // 0 for gei0 and 3 for gei3
I use gei0 and gei3 to communicate with other machines, and
gei2 to fetch the VxWorks file. I do not use gei1 at all. I do not attach and bring gei2 up but it initially serves as up.
Furthermore, when I runipDetach(2, "gei") and ipAttach(2, "gei") functions respectively, gei2 serves as UP RUNNING.
There is a switch connecting computer0 and computer2. The
Ethernet cable of computer0 is attached to gei3 and one of the
switch ports. Same for computer2 as well.
I use VxWorks v6.9, C++98, and Windriver Workbench v3.3.

Related

USB port to detect "close" or "open" switch

I need to make a program that would play a sound as I press a push button switch. My idea is to use the USB port, and that if I short 2 wires from it (like for example the data+ and data-), the program would play a sound repeatedly while the 2 wires are shorted. Is my idea possible and simple to do? Can you please help me do it using VB? Thanks a lot for any help.
No, that is not practical. USB ports do not have that feature is far as I know. There are plenty of small, cheap USB microcontroller boards that are up to the task though.
For example, you could get an A-Star 32U4 Micro, program it using the Arduino IDE, and make it send a certain message on the its virtual COM port (which is accessed from the Serial object) when a button is pressed and another message when it is released. Then in Visual Basc, you would use the SerialPort class to connect to the A-Star's COM port and listen for that message.
USB ports are mainly used for transmitter and receiver communications for data transfers. They are not used for open or closed switch detection. In order to use a USB port for switch detection, you can used a serial to USB conversion breakout board with a specialized IC chip designed to detect an open or closed switch and communicate this via the USB protocols to send out a communications data transmission that a switch has just been open or closed. Then you would program an application in any language to listen on that USB port for this specific data transmission for a closed or open thrown switch. You can potentially detect about 4 switches opened or closed simultaneously if you want. And this serial to USB breakout board can easily be purchased online at:
https://www.sparkfun.com/products/199

How to prevent an I/O Completion Port from blocking when completion packets are available?

I have a server application that uses Microsoft's I/O Completion Port (IOCP) mechanism to manage asynchronous network socket communication. In general, this IOCP approach has performed very well in my environment. However, I have encountered an edge case scenario for which I am seeking guidance:
For the purposes of testing, my server application is streaming data (lets say ~400 KB/sec) over a gigabit LAN to a single client. All is well...until I disconnect the client's Ethernet cable from the LAN. Disconnecting the cable in this manner prevents the server from immediately detecting that the client has disappeared (i.e. the client's TCP network stack does not send notification of the connection's termination to the server)
Meanwhile, the server continues to make WSASend calls to the client...and being that these calls are asynchronous, they appear to "succeed" (i.e. the data is buffered by the OS in the outbound queue for the socket).
While this is all happening, I have 16 threads blocked on GetQueuedCompletionStatus, waiting to retrieve completion packets from the port as they become available. Prior to disconnecting the client's cable, there was a constant stream of completion packets. Now, everything (as expected) seems to have come to a halt...for about 32 seconds. After 32 seconds, IOCP springs back into action returning FALSE with a non-null lpOverlapped value. GetLastError returns 121 (The semaphore timeout period has expired.) I can only assume that error 121 is an artifact of WSASend finally timing out after the TCP stack determined the client was gone?
I'm fine with the network stack taking 32 seconds to figure out my client is gone. The problem is that while the system is making this determination, my IOCP is paralyzed. For example, WSAAccept events that post to the same IOCP are not handled by any of the 16 threads blocked on GetQueuedCompletionStatus until the failed completion packet (indicating error 121) is received.
My initial plan to work around this involved using WSAWaitForMultipleEvents immediately after calling WSASend. If the socket event wasn't signaled within (e.g. 3 seconds), then I terminate the socket connection and move on (in hopes of preventing the extensive blocking effect on my IOCP). Unfortunately, WSAWaitForMultipleEvents never seems to encounter a timeout (so maybe asynchronous sockets are signaled by virtue of being asynchronous? Or copying data to the TCP queue qualifies for a signal?)
I'm still trying to sort this all out, but was hoping someone had some insights as to how to prevent the IOCP hang.
Other details: My server application is running on Win7 with 8 cores; IOCP is configured to use at most 8 concurrent threads; my thread pool has 16 threads. Plenty of RAM, processor and bandwidth.
Thanks in advance for your suggestions and advice.
It's usual for the WSASend() completions to stall in this situation. You won't get them until the TCP stack times out its resend attempts and completes all of the outstanding sends in error. This doesn't block any other operations. I expect you are either testing incorrectly or have a bug in your code.
Note that your 'fix' is flawed. You could see this 'delayed send completion' situation at any point during a normal connection if the sender is sending faster than the consumer can consume. See this article on TCP flow control and async writes. A better plan is to use a counter for the amount of oustanding writes (per connection) that you want to allow and stop sending if that counter gets reached and then resume when it drops below a 'low water mark' threshold value.
Note that if you've pulled out the network cable into the machine how do you expect any other operations to complete? Reads will just sit there and only fail once a write has failed and AcceptEx will simply sit there and wait for the condition to rectify itself.

Debugging an intermittently unresponsive USB device

My app communicates with a simple USB device as follows:
The app sends commands (2 or 3 bytes each) to the USB device by using WriteFile (kernel32.dll).
For each command that is send, the USB device sends a short response, which the PC receives using ReadFile (kernel32.dll).
Reading and writing is done asynchronously, using GetOverlappedResult to check the status of an operation.
Testing on 2 out of 3 PCs, the app and device function perfectly: all responses are received 100% reliably.
Under identical tests on the third PC, approximately 50% of the ReadFile requests do not return any data - the status remains as pending (ERROR_IO_INCOMPLETE) forever.
In other words, approximately for every 2 commands sent, one response is received.
Because the device functions perfectly with the other PCs, it lead me to believe that the problem might be occuring inside Windows, in the underlying code which is called by ReadFile (I presume some lower level USB driver code).
Question:
Please could you advise what debugging tool is most useful to investigate this? With my current knowledge, the internal workings of ReadFile are quite opaque.
The PC which is experiencing the issue is running Windows 8.0
You could try DebugView. Run as admin.
Go to "Capture", enable "Capture Kernel", enable "Enable Verbose Kernel Output".
This might help to investigate errors on Kernel level, if any occured.

Sending AT commands from an embedded system to a Fastrack Supreme Wavecom Module

I have an embedded system that controls a motor using pwm and some other things, I send commands through a serial connection, which is connected to a Fastrack Wavecom Supreme GSM Module. However, the module connected to the embedded system (the client), fails to send the message to the server module.
I have been able to send messages back and forth between the two wavecom modules, however, when I try and send from my PIC18F45k22 to the wavecom module, it fails.
Any ideas of what could be going wrong?
You did not specify what type of serial communication you are using. For instance, if you are using the PIC's SPI module you may be sampling on the wrong edge of the clock. There are at least 2 common SPI modes widely used and 4 all together. If you are using the PIC's UART there are "a whole bucket full" of setting that may be off. Speed, number of bits, in band signaling, out of band signaling, parity, ect.

PySerial: Create serial object without opening port

I'm running some code on Arduino, I have website with a slider which uses a cgi script to pass values to Python. Then the python script uses pySerial to send the values to Arduino which controls a motor.
The plan was to be able to control the motor speed using the slider on the website.
However I seem to be coming up against a problem of the Arduino resetting whenever I change a value on the website, causing the motor to stop. Is there any way around this? My python code is below.
#!/usr/bin/env python
import cgi
form=cgi.FieldStorage()
import json
ser = serial.Serial('dev/ttyACM0', 9600)
#I think there should be a sleep here for 1.5 seconds
ser.write("%s\n" % (form["value"]))
ser.close()
print "Content-type: application/json"
print
print(json.JSONEncoder().encode({"status":"ok"}))
So, say I have the motor running at 50% speed, then change a value on the website, it runs this script which executes the serial.Serial('dev/ttyACM0', 9600) command. That opens the port which resets the arduino, stopping the motor before passing the new command.
Is there any way to pass ser.write("%s\n" % (form["value"])) to the arduino without freshly opening the port? Such as leaving the port open between python sessions?
If not, is there any other way around this problem?
I believe the reset is due to a hardware design of the specific Arduino device you are using. I suggest using an Arduino Micro or Leonardo board instead. They use a virtual serial port and should not restart your sketch each time a serial port is opened. This is from the Arduino site:
No reset when you open the serial port.
Unlike the Arduino Uno, the Leonardo and Micro won't restart your
sketch when you open a serial port on the computer. That means you
won't see serial data that's already been sent to the computer by the
board, including, for example, most data sent in the setup() function.
Serial re-enumeration on reset.
Since the boards do not have a dedicated chip to handle serial
communication, it means that the serial port is virtual -- it's a
software routine, both on your operating system, and on the board
itself. Just as your computer creates an instance of the serial port
driver when you plug in any Arduino, the Leonardo/Micro creates a
serial instance whenever it runs its bootloader. The board is an
instance of USB's Connected Device Class (CDC) driver. This means that
every time you reset the board, the USB serial connection will be
broken and re-established. The board will disappear from the list of
serial ports, and the list will re-enumerate. Any program that has an
open serial connection to the Leonardo will lose its connection. This
is in contrast to the Arduino Uno, with which you can reset the main
processor (the ATmega328P) without closing the USB connection (which
is maintained by the secondary ATmega8U2 or ATmega16U2 processor).
This difference has implications for driver installation, uploading,
and communication...
I you might be able to use the setDTR(False), but I have tested this yet. A while back they fixed the bug that were initially associated with setDTR. What operating system are you use this on?
ser = serial.Serial('dev/ttyACM0', 9600)
ser.timeout = 1
ser.setDTR(False)
Let us know if this does not work.