Any examples of using objects from the OBEX?
blittled
Posts: 681
I have noticed that the PropGCC has an example using TV Text but I found it a bit vague and was hoping there are other examples I can look at to get familiar with _Driver.H and how to implement the hooks into stdio.
While I'm on this I was wondering about the px.bat file mentioned in tv_text.h. Does this need to be used on any OBEX object? If so where is it located?
While I'm on this I was wondering about the px.bat file mentioned in tv_text.h. Does this need to be used on any OBEX object? If so where is it located?
Comments
You should be able to take any SPIN demo "driver" from OBEX and convert it to a C program assuming the SPIN/PASM interface is "clean" - that is not interdependent. The Mems Accelerator, Mouse, TV, and VGA demos are all clean as far as I can tell. Some examples where the interface is not clean are the Graphics demo and Keyboard demo.
Configuring the standard library driver interface is described here: http://propgcc.googlecode.com/hg/doc/Library.html#drivers
Using a driver is very simple. Writing a driver is a matter of providing functions like open, read, write, and close.
One simple example for using a driver is in the xbasic demo.
I decided to use the full duplex serial driver for xbasic so I could use copy/paste for a demo. The stock 1 COG LMM serial IO has limits because input must be polled - it works fine if you don't do copy/paste.
To add the full duplex serial driver to xbasic all I had to do was paste this snippet in the main file:
Nothing to it. It works because GCC has the ability to overload features. That's just one of several GCC super powers.
In this case, the first and only location in the list is the full duplex serial driver. The first location is reserved for the console and is the reason you don't have to define special printf functions. If you want smaller printf functions that do not use floating point, etc... you can add the " -D__simple_printf " flag when compiling with the standard library.
Writing a driver takes more work.
That process has not been fully explained, but the TV Text demo has example code. As you say, it is vague.
For a standard library driver, you need to define the functions, and add the functions to a _Driver array.
One of the simplest possible examples of a driver is the null driver. The null driver is used in some cases where you don't want anything to happen - it is often used in Linux output redirection if you don't want some program to print stuff.
The null driver does nothing, that's why it's so simple. But it does illustrate the basics of a driver. It provides functions and glues them together in the _Driver array. Here's a brief example where all driver functions are illustrated.
The driver functions do anything you want them to do. The _Driver array tells the program what function code to use for the driver to call when you say "fopen", etc... In the case of the full duplex serial driver shown in the xbasic example, any print output translates to the write function automatically because that's what the first _Driver slot is for.
In the TV example, these functions are defined:
The _Driver array looks like this:
The c3file demo also uses a generic driver. The source code is not in one of our test distributions, but it follows the same idea.
+1 for "GCC Super Powers"
Jazzed, can I get a few words on what "clean" means? Right now, I'm authoring some PASM, and have some targeted for a project, and am unsure about "clean". Best sort it right now.
@potatohead,
Basically it means that we should use mail-boxes for sharing information between the host language and the PASM driver. The PASM should stand alone independent of symbols or functions outside of the DAT block.
For example, the Graphics driver references fontptr which is a long in the PASM, but is given a value in the SPIN start method. In this case, I had to rewrite the Graphics initialization for use with C. I have seen lots of inter-dependencies with SPIN/PASM drivers.
Now, if the same driver was rewritten in GAS, you could share variables between GAS and C. The demos/toggle/gas_toggle program shows how to do this.
However, in some ways, I would like to see no inter-dependencies in any ASM at all. That would allow loading PASM code as needed which could save HUB memory space. We do that quite a bit in the loader.
There are probably other things we've learned as a group about this subject that would apply.
Thanks,
--Steve
Method 1:
Cogstart with block address passed via PAR, longs are read or written to in a periodic way to change modes, or communicate a state.
Method 2:
Cogstart with block address in PAR, arguments are dropped into the block of longs, then one in particular is written, triggering some action in that COG, that when complete, results in that same command long being written to again to signal done/ready.
Both are basically the same mechanics.
Are you saying GAS has to assemble those to make use of them? Or...?
**I'll look up the font pointer example. I think you mean "poke it in", where the cog image is modified prior to cog start. If so, agreed. That one isn't good. But do the means above work reasonably well?
To explicitly refer to an external symbol (without passing it in PAR) you need to rely on GAS, which can export the symbol reference in a form the linker can resolve. The gas toggle example shows how to do this.
Eric