How to access the functionality in _FdSerial_rxcheck(FdSerial_t *data);
StevenW
Posts: 6
First off, any sample code for the FullDuplexSerialDriver would be SUPER appreciated.
But - to my question - Does anyone know how I can use this method:
It's exactly what I'm looking for - a non-blocking check to see if data is available or not, and, if so, what it is.
However, with this stuff getting wrapped into those "standard driver" templates, this method isn't exposed through the standard FILE * interface. I checked, and a reference isn't getting passed to the driver stuff at all for it:
I tried to copy-paste the FdSerial stuff into my own project, but the references to propdev.h were screwing me up - and getting the ASM loaded properly seemed too daunting of a task to me.
Ideas?
But - to my question - Does anyone know how I can use this method:
/**
* rxcheck gets a byte from the receive queue if available
* function does not block.
* @returns receive byte 0 to 0xff or -1 if none available
*/
int _FdSerial_rxcheck(FdSerial_t*data);
It's exactly what I'm looking for - a non-blocking check to see if data is available or not, and, if so, what it is.
However, with this stuff getting wrapped into those "standard driver" templates, this method isn't exposed through the standard FILE * interface. I checked, and a reference isn't getting passed to the driver stuff at all for it:
_Driver _FullDuplexSerialDriver =
{
_FullSerialName,
fdserial_fopen,
fdserial_fclose,
_term_read,
_term_write,
NULL,/* seek, not needed */
NULL,/* remove */
_FdSerial_getbyte,
_FdSerial_putbyte,
};
I tried to copy-paste the FdSerial stuff into my own project, but the references to propdev.h were screwing me up - and getting the ASM loaded properly seemed too daunting of a task to me.
Ideas?
Comments
For anyone who wants the hack-fest:
Your way of directly peeking into the driver will work (obviously). Another approach would be to restructure the program so that the file I/O is in a separate thread (and hence you don't need to worry about it blocking).
Eric
Welcome to the forums. I hope your Propeller experience has been good so far.
To use FullDuplexSerial as a stdio device, all you need to do is add this to your code:
http://forums.parallax.com/showthread.php?140098-New-Program-Demonstrates-Variable-Patching&p=1098308&viewfull=1#post1098308
Hope this helps.
I see Eric has already answered the rest of your question.
Thanks,
--Steve
Yeah... I know But the "driver" for this particular type of "device" does. I guess my "question" was really a two-parter... the first part is a question "am I missing something?" and the second part was more of a commentary/statement about the flexibility of the current driver design.
In other words...
Is there a standard mechanism (or have the designers of the "driver" system thought about developing a standardized mechanism) for consumers of drivers (myself, in this case) to access features of a driver which are specific to the driver itself? Also; will any similar driver(s) developed to use these standard interfaces be shoehorned into this limited (IMHO) set of features?
In my world what I'm looking for is something more akin to classes and subclasses. In this case I have a FILE reference, but there is no built-in facility to get me from there to the underlying FdSerial_t reference. Instead I have to rely on this kludge: fp->drvarg[0] which may or may not continue to work when new versions of the drivers and/or driver subsystems get released.
Also, there is no way for me to reference the actual FDS header file - which means I need the wonky extern declaration. This is also (again, IMHO) a library/architecture design failure.
Honestly, I've been working on my little hobby project quite a bit over the last two weeks in Prop GCC - and I LOVE it... but I really think this Driver subsystem needs to be rethought - because it's not flexible enough for me to build and represent the various peripherals in my project.
For example; I have 4 "buses" or interfaces between my micro and my peripherals; an I2C bus, an SPI bus, some pulse width based peripherals, and some serial peripherals. If I had to limit my interactions with these devices to what's available in stdio.h, I'd be sunk. Below is my example of using my personal SPI bus implementation for a RTC:
SPIBus * bus = createSPIBus(2, 3, 4);
SPIDevice * rtc = createSPIDevice(bus, 1);
The declarations of those methods are:
SPIBus * createSPIBus(int clockPin, int misoPin, int mosiPin);
SPIDevice * createSPIDevice(SPIBus * bus, int chipSelectPin);
I don't need any wacky formatting string that specifies the driver and what not... nor does anyone need to reference documentation to see what the order of things in that format string is. The parameters are spelled out; clockPin, misoPin, mosiPin.
I can't fit my SPI implementation into the "standard" driver subsystem without complicating my SPI code and sacrificing features.
It's my understanding that the developers' idea behind the standard drivers was to help reduce codebase fragmentation and/or foster greater code reuse... and that's all great. But I'm not sure this design is going to help.
Just my $0.02
I think there's a misunderstanding here, probably due to the limited documentation. The _Driver structure is really just the interface between drivers and the C stdio facilities like fopen(), fread(), and fwrite(). Perhaps it should better have been named "_StdioDriver". It's not intended that all hardware drivers have to use this structure. If your SPI driver doesn't naturally lend itself to stream I/O, then there's really no need to try to fit it into the stdio framework. (In principle, of course, all drivers could be controlled via stdio, as the Plan 9 OS demonstrated, by sending all commands and reading all status as ASCII. But in a hardware constrained environment like the Propeller this is overkill :-)).
There is as yet no general framework for drivers, because the range of possible hardware is so vast. A set of classes and subclasses sounds like an excellent idea, and we're certainly open to suggestions from the community.
Eric
Great info... thanks!
Yeah, while it wasn't immediately apparent, I did pretty quickly understand that they were stdio-specific drivers.
My suggestion:
The Full Duplex Serial "Driver" uses the standard, perfected, ASM everyone has been using. That's great! Also, the C code over top of the ASM exposes some great methods. That's also great. My problem is:
The code for the full duplex serial stuff isn't exposed in a way that makes it possible for me to instantiate/use those bits separately from the STDIO driver stuff. The foundational bits that let me read/write to a serial device should be unhinged from the STDIO driver, and the interface should be cleaned up a bit. The STDIO driver for the "FDS:" prefix should be a thin layer on top of the unhinged FDS bits.
Also, there is a wealth of good solid ASM already available on the OBEX... a tutorial on integrating ASM bits into my C code would really help expedite our ability to port a number of existing assets over to Prop GCC. The more ports of existing code we have for Prop GCC, the more people will use it.
Thanks again for the response.
- Steve
Eric's spin2cpp program solves much of this. It is getting a pretty big workout right now.
I've added your tutorial request to the propeller gcc issues list. http://code.google.com/p/propgcc/issues/detail?id=52
Thanks,
--Steve
Great! Thanks!
FWIW, I could probably help start/contribute the tutorial if I had some sample code I could work through. Right now the only example(s) of integrating ASM with my C code in PropGCC are the two serial drivers - and both of those use a method I don't seem to have access to outside of the internal libraries.
That would be wonderful. I'm spread very thin these days as are others.
There are some examples of FullDuplexSerial and TV/VGA without hooking up to stdio around.
The basic tenet of interfacing PASM and C is that all setup and communication must be via a mailbox. When I ported GraphicsDemo.spin I had to add an initializer for one of the DAT variables.
Another key for PASM drivers is that the object variable start name is _binary_<file>_dat_start . That is slightly different from COG C variable names such as _load_start_<file>_cog and _load_start_<file>_ecog .
Here are some links:
SimpleIDE TvKbFile for C3 (uses stdio) http://forums.parallax.com/showthread.php?140098-New-Program-Demonstrates-Variable-Patching&p=1098308&viewfull=1#post1098308
Lots of things ported to ICC when it was supported are here: http://forums.parallax.com/showthread.php?135761-ICCV7-C-Code-Posted-Here-OBEX-changes-to-accommodate-GCC&p=1050441&viewfull=1#post1050441
The ICC package includes my original FdSerial code.
Thanks,
--Steve
Perfect!! Thanks! I'll follow up at some point with a comment on the Google Code "Issue" with a starting point for a tutorial!
There are also some examples in the library source code, which is available by checking out the propgcc project or by downloading just the library source archive. Look in the lib/drivers/ subdirectory.