Another SerialPort question - avoid reboot
ypapelis
Posts: 99
I appreciate all the help in getting control of the serial port code especially as it related to stdio. My next question has to do with avoiding the reboot that occurs when serial I/O is taking place but there is no usb connected to the board. I am using a few different boards, and they all exhibit the same behavior. In Spin, avoiding doing any I/O addresses the problem. In C, I am getting reboots, even though there is no printf taking place.
What I want to do is select at runtime (based on the state of an input pin) if I will do console I/O or not. If the selection is to use console I/O, it's ok to reboot when no USB is present as that mode only makes sense when there is serial terminal attached. However, when the setting is to ignore I/O, I want the program to function even when no USB port is connected. I still want to keep the full duplex driver alive, as I am using it for serial I/O in other pins, but I have not found a way to prevent the reboot.
I tried to create a 'Nothing' driver, by using _null_read and _null_write and then use freopen() to re open stdin/out/err, however the compiler complains; I noticed that stdio is defined as a pointer to an array, so it cannot appear on the left hand side of an assignment, as required by freopen.
Another thing I tried was this:
__files[0]._drv = &_NothingDriver; __files[1]._drv = &_NothingDriver;
__files[2]._drv = &_NothingDriver;
The printf's disappeared (i.e., no more output) but when I pull out the usb cable and reboot, the program keeps rebooting.
I'm sure there has to be an obvious way to do this, but I have not figured it out yet!
What I want to do is select at runtime (based on the state of an input pin) if I will do console I/O or not. If the selection is to use console I/O, it's ok to reboot when no USB is present as that mode only makes sense when there is serial terminal attached. However, when the setting is to ignore I/O, I want the program to function even when no USB port is connected. I still want to keep the full duplex driver alive, as I am using it for serial I/O in other pins, but I have not found a way to prevent the reboot.
I tried to create a 'Nothing' driver, by using _null_read and _null_write and then use freopen() to re open stdin/out/err, however the compiler complains; I noticed that stdio is defined as a pointer to an array, so it cannot appear on the left hand side of an assignment, as required by freopen.
Another thing I tried was this:
__files[0]._drv = &_NothingDriver; __files[1]._drv = &_NothingDriver;
__files[2]._drv = &_NothingDriver;
The printf's disappeared (i.e., no more output) but when I pull out the usb cable and reboot, the program keeps rebooting.
I'm sure there has to be an obvious way to do this, but I have not figured it out yet!
Comments
What board(s) are you using?
I'm pretty sure this is a hardware related issue masked by a software hack and some current from the propeller pins powering the USB port. The USB VCCIO is unconnected when the USB cable is removed on most designs.
I'll look into the specifics of your situation tomorrow.
I am using the old stingray MSR-1 controller board, but I'm pretty certain the same issue occurs in other boards as well (the project I am working on also involves the Propeller ASC board from mghdesigns. My understanding of that is that serial port activity on pins 31/30 often triggers to same mechanism that the boot loader uses to initiate program download, but I am frequently wrong so don't take my word on it.
See if this thread answers your question.
http://forums.parallax.com/showthread.php?135067-Serial-Quirk&p=1043169&viewfull=1#post1043169
A small amount of code at the beginning of your program can determine if the USB is plugged in or not.
Beau,
Thanks for the recommendation, but unfortunately, it did not fix it for me. I think the issue is that by the time the 'main' function is called, the serial port driver has already done its damage and the chip reboots before I have a chance to shut down the tx pin.
By the way, that is when using the _FullDuplexSerialDriver. If i use the _SimpleSerialDriver, the trick works. However, I need FDS because in order to build my rudimentary GUI using console I/O, I need to check for a character without blocking, which as of now is only possible on FDS.
There may be another hack that can address the issue (I was wondering about the InitIO function, I saw that mentioned in the wiki, but can't figure out the proper signature); I also considered effectively replacing the driver at runtime, but I have wasted so much time on this so far, I'll give up, and simply have to download a different version of the program to support console I/O.
How would I close and reopen the driver? Using freopen does not work since stdin/out are not l-values, and I am not handy enough with the details of the drivers to do this. A piece of working C code would be greatly appreciated.
I thought of the latter recommendation (effectively replacing the device driver by copying over it), but I have spent so much time on this, all sense of daring is lost. The former recommendation wastes a COG and I can't afford that since my project is using all 8 of them right now. When I get some time, I will try it though, just to know. Or better yet, I could wait for the next version of the propgcc which will expose the non-blocking flag and use the simple driver which does not occupy a COG. I am liking that last option a lot -:)
Another idea is to use the Spin-like variation of the FullDuplexSerial driver. That way you can start it when you are ready.
Noticed you're running out of cogs. Is it possible to combine more than one feature in a cog?
I'll make another distribution soon for testing with the non-blocking flag.
You can still do freopen: The value returned by freopen is just the same one you passed in, unless there is an error (in which case NULL is returned). There's no need to assign to stdin, stdout, and so on.
Regarding the quick start board.
I am committed to using the stingray MSR1 board, since my first propgcc project is programming the Stingray to be used in a robotics class I am teaching next semester. I have 5 stingrays, each containing two propelelr boards, the MSR1 and an ASC board for sensor reading. So unfortunately, I don't have the luxury of picking at this point.
Regarding using the spin-like variation.
That will probably work; but I started using the FDS and I would have to recode/re-type the GUI. Probably will take a couple of hours, so if everything else fails that may be an option.
Regarding running out of cogs.
I am using one cog for the main loop, one cog for the FDS, one cog for controlling the stingray motors (I use cogc for generating PWM and implementing a PID loop for velocity control one each motor), two cogs for talking to the sensor board (one for the loop and one for the cogc device driver that implements an SPI-like protocol), and two cogs for the main loop talking to the main control processor (one for the loop and one for the FDS). I splurged and used a whole cog just to animate an LED to provide status information. Other than folding the LED animation in the main loop, the biggest gain would come from being able to use a serial port driver that can talk to multiple ports without requiring a cog per port (like the FullDuplexSerial_r004). Any chance of folding that capability in there ?
@Dave Hein,
You are correct; thanks for pointing that out.
@ersmith
Didn't realize you didn't have to re-assign the file pointer. That may be another thing to try when able.
--Thanks
If it works with Spin, it should be able to work with propeller-gcc.
It's really nice to hear that you're getting so much utility out of cogc.