Large programs in C++
Dr_Acula
Posts: 5,484
I've got stuck thinking about large programs and I would be grateful for some advice.
The fundamental problem is - where do you store a large program and how does a program access the same storage?
Let's say the program is stored in external ram. If your code wants to access that same ram, you have to disable the cache driver.
Ditto if the program is running from an SD card. You have to disable the cache driver to access the SD.
There are solutions and there is code to put the cache to sleep. But that is specialised C code and won't work with the Spin To C converter. Also it implies that the memory driver sits in hub (eg SD driver), and if you have devoted hub ram to a cache and also to a screen buffer there may not be much room left.
The more I think about this, the more I wonder if the simplest solution is two separate types of memory. One is for the code, and one is for data. It might be two SD cards. It might be two ram chips (though they can't share the same pin so more likely serial than parallel). It might be a hybrid - eg flash ram and an SD card.
I wonder which is the best? For data storage, sram will be better than flash. But sram is usually parallel and parallel uses up lots of pins. Serial sram could be an option. For running the code, is flash better or is an SD card better? SD cards are probably the cheapest per gigabyte, but then again, a program is not going to be a gigabyte as it will take ages to download. On the other hand, the removeable nature of SD cards could be the answer .
Or would it be better to have an SD card for the program, an SD card for storage of bitmaps and text files, and some serial sram for data (so you can free up hub space for more cache)?
Or is flash better?
I'd really appreciate everyone's thoughts.
The fundamental problem is - where do you store a large program and how does a program access the same storage?
Let's say the program is stored in external ram. If your code wants to access that same ram, you have to disable the cache driver.
Ditto if the program is running from an SD card. You have to disable the cache driver to access the SD.
There are solutions and there is code to put the cache to sleep. But that is specialised C code and won't work with the Spin To C converter. Also it implies that the memory driver sits in hub (eg SD driver), and if you have devoted hub ram to a cache and also to a screen buffer there may not be much room left.
The more I think about this, the more I wonder if the simplest solution is two separate types of memory. One is for the code, and one is for data. It might be two SD cards. It might be two ram chips (though they can't share the same pin so more likely serial than parallel). It might be a hybrid - eg flash ram and an SD card.
I wonder which is the best? For data storage, sram will be better than flash. But sram is usually parallel and parallel uses up lots of pins. Serial sram could be an option. For running the code, is flash better or is an SD card better? SD cards are probably the cheapest per gigabyte, but then again, a program is not going to be a gigabyte as it will take ages to download. On the other hand, the removeable nature of SD cards could be the answer .
Or would it be better to have an SD card for the program, an SD card for storage of bitmaps and text files, and some serial sram for data (so you can free up hub space for more cache)?
Or is flash better?
I'd really appreciate everyone's thoughts.
Comments
Also, Propeller GCC already has code in it to share the SD card between the filesystem and the SD cache driver.
I need to be thinking clearly about this, because what would be great would be to think of a way to take an existing Spin program and convert it to C and somehow preserve the SD part. So you might have a Spin program with fsrw or Kye's driver, and the function calls are things like "open" and "read n longs" and "close". So one could maybe think about a pre-processor that takes that spin code and translates it to C handles, and then do a spintoC conversion and maybe paste back in that C code.
I've tried a number of times to start writing a large GUI operating system for the touchscreens but there are a few problems I have come up against, and one of them is the integration of pasm with a higher level language. I found some solutions for catalina by writing my own custom IDE but I think a better answer is to write code in Spin as this makes the entire obex available.
I'll think about this some more as I'm still not quite sure I can explain exactly what the problem is! Suffice to say I think there is a solution that is tantalisingly close here.
Solutions are:
- Don't try to run XMMC from SD card
- Let go of SPIN and use C/C++ entirely
The Spin2Cpp converter is great for converting spin to C++, but I don't think it was intended to be a Spin/C++ daily language swap tool. Spin is designed for using HUB RAM only - whatever you can load there will run. Spin2Cpp won't give you big spin unless you let go of trying to run from SD card.Or, manually edit your C code (and/or the spin2cpp output) to add __attribute__(section(".hubtext")) to the low level routines that need to access SDRAM; but putting them in the HUB memory you can make sure the cache COG is not conflicting with them.
Eric
For 30 dollars or so the ARM board gives you ethernet, USB, SD card, easy WIFI if you want it, etc etc.
As you know, I like to squeeze a quart into a pint pot but at some point you have to give up.
Yes, that idea has crossed my mind a while back.
Who says all COGs have to be COG? One of them could be an ARM with similar access into HUB space but otherwise running from a Giga Byte of RAM.
Thing is, as an educational tool introducing the uninitiated to programming and electronics and the general operation of a CPU the propeller is totally briliant.
This kind of introduction to computing is exactly what the Raspberry Pi is all about.
I do wonder though that with the basic mechanics of the ARM hardware being burried under a ton of Linux and closed source graphics and other drivers how well that idea can work.out. It all gets too complex.
On the other hand in the industrial world the Prop soon runs out of steam. By the time you have to move to C/C++ to get the job done its far to big to fit and mind bendingly slow.
Conclusion: ARM with access to HUB on the same chip is perfect.
Saves me building the "Propeller Pi" board:)
I don't want to come over all negative. I think the Prop is great at what it does and Parallax is one cool company.
As for the rest of your post, I totally agree.
Can the pi run a touchscreen? I think there are some cool things we haven't done yet with the prop, and I still think it can be done cheaper than the Pi if you compare like with like (ie mass produced surface mount).
Re dual SD, I just realised that with a dual touchscreen you get two SD sockets for free, and with 3 wire links I think I could use the second SD card.
However, with all the great ideas above I can see some other solutions.
A question re C - can you put inline pasm in a C program? I know there is something called GAS? but is there a pasm solution. If not, I'll have a think about that because there is one for catalina and it should not be too hard to replicate for C++.
jazzed said
Great points. First one has got me thinking - with the 1 meg of sram on the boards I am using, it should be possible to run the program from external ram via the cache. The drivers are pretty simple - write n longs or read n longs. The way they work is based on Cluso's design where you have a cog waiting for a command and the command is to do things like read or write. The code hangs until the cog has finished. That means there is automatically no conflict issue. If the cache driver is fetching a block then it won't let the program continue. If the program is fetching a block then the cache driver will have already got its block. It is fully deterministic because the cog is being used in a non parallel way in this instance. If someone wants to write a driver I should be able to find a spare freebie board.
Point 2 - use C. I agree, and ultimately the aim would be to take the entire obex, run each one through the spintoc converter and then use these objects in C as C code. However, there could still be instances where one wants to tweak the pasm code and change it every compile/download which is where I think it could be useful to have code with inline pasm rather than the cog code being .h files with arrays in hex.
Just use part of it for cache and part of it for buffering. You can share a lock efficiently to arbitrate the bus because cache uses block transfers, and cache locks only when a swap is necessary.
I don't understand the need to take the entire obex and run it through the spin2cpp converter.
Trying to port a spin program that uses fsrw or kyedos to run on xmmc from sd card is abusing spin2cpp; it is an unreasonable thing to do.
Using converted programs in LMM is fine, but non-trivial programs will be too big until Eric finishes his compression scheme.
Where would I find the ram driver code for the dracblade board? ( c:\propgcc\which folder?) I think someone wrote a driver for that board and I am hoping I can modify it for the touchburger ram.
I'm looking for the primitives that do things like move data in and out of the cache. It should be simpler than the SD cache as it won't need an SD driver.
Sure. Can a Prop play HD videos on an HDMI TV?:) No doubt about it.
[/QUOTE]
Depends on what it is, horses for courses as always.
Want lot's of I/O pins? The Prop is your device.
Want real time control of said pins? The Prop is your device.
Want low standby power consumption? The Prop is your device.
Want large C++ programs that don't run at snails pace? Let's get the Prop some assistance with that.
Ah that might explain things, I don't seem to have a propgcc/loader directory. I'll see if it is on the web somewhere...
Addit: found it http://code.google.com/p/propgcc/source/browse/loader/spin/dracblade_cache.spin?name=v0_2_1
That should work. So replace this
with this (plus a few more lines not shown)
Ok, so say we have some code written, what needs to be recompiled and how do you do this?
I suppose some changes are necessary for the new board.
I'm sure there was a thread where Joe and I discussed this and posted versions, but I can't find that now.
Joe and I have a few things to sort out as we have changed the schematic so the driver needs changing. But that code will be a great framework as most things are just going to be cut and paste from the new driver code.
In order to get this to work we have groups of pins, so a possible scenario is that the C program is talking to the finger input of the touchscreen/serial port etc and in order to do a cache fetch it may need to formally shut down things using those pins. Possibly even unload a cog then reload it again. Some of that code is a few lines of spin and I note the attached driver is all pasm, so will we need to translate it to pasm?
If yes, then it can be done, just need to think more about the code. At the moment, group 1 and 2 are for the display and fast ram access, group 4 is going to be VGA and TV and keyboard so you can run demoboard programs, and group 3 is probably going to be the default for a running program. Group 3 at the moment is a SPI A to D chip and the SPI driver reading the finger on the screen. It might turn out that if we use SPI things that simply deselecting the /CS line is enough to disable the device, in which case the cache driver will be very simple and we will be able to do it all in pasm.
Thanks++ for that code, I think I now have a clearer idea of what will be needed.