C-DOS
Dave Hein
Posts: 6,347
I've done some more work on the EEPROM file system, and I discovered I could load individual spin objects and relocate them by manipulating the object offsets.· So I decided to develop a disk operating system I call C-DOS.· I call it C-DOS because it relies heavily on the clib object I checked into the OBEX.
The current version of c-dos uses the second half of the boot loader EEPROM for the file system.· When you first start cdos you are prompted to use the format command to format the EEPROM.· You can then·use the appcall command to run the default app, which will load three small apps onto the file system.
Currently, a c-dos app can only consist of a single object that must include the clib and eefs object.· The operating system will call a method named "main", which·must be defined as
PUB main(argc, argv)
argc indicates the number of arguments that are passed, and argv is an array of string pointers containing "argc" entries.· The c-dos app object cannot use any variables defined in a VAR section, and must only use variables on the stack or in a DAT section.
I have attached the three spin files that implement c-dos, the EEPROM file system and the c-dos default app.· Let me know if you have any questions or coments.· BTW, c-lib must be loaded into the Prop's RAM using the F10 key, and not into the EEPROM using the F11 key or you will wipe out the EEPROM file system.
You will also need clib and Basic_I2C_Driver from the OBEX.
Dave
Post Edited (Dave Hein) : 4/11/2010 9:38:38 PM GMT
The current version of c-dos uses the second half of the boot loader EEPROM for the file system.· When you first start cdos you are prompted to use the format command to format the EEPROM.· You can then·use the appcall command to run the default app, which will load three small apps onto the file system.
Currently, a c-dos app can only consist of a single object that must include the clib and eefs object.· The operating system will call a method named "main", which·must be defined as
PUB main(argc, argv)
argc indicates the number of arguments that are passed, and argv is an array of string pointers containing "argc" entries.· The c-dos app object cannot use any variables defined in a VAR section, and must only use variables on the stack or in a DAT section.
I have attached the three spin files that implement c-dos, the EEPROM file system and the c-dos default app.· Let me know if you have any questions or coments.· BTW, c-lib must be loaded into the Prop's RAM using the F10 key, and not into the EEPROM using the F11 key or you will wipe out the EEPROM file system.
You will also need clib and Basic_I2C_Driver from the OBEX.
Dave
Post Edited (Dave Hein) : 4/11/2010 9:38:38 PM GMT
Comments
cheers .... BBR
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cheers ... brian riley, n1bq, underhill center, vermont
The Shoppe at Wulfden
www.wulfden.org/TheShoppe/
www.wulfden.org/TheShoppe/prop/ - Propeller Products
www.wulfden.org/TheShoppe/k107/ - Serial LCD Display Gear
Dave
Mentioned this in the bst thread as well (http://forums.parallax.com/showthread.php?p=755835).
Post Edited (kuroneko) : 4/12/2010 2:32:57 PM GMT
Just a few comments about how I dynamically load apps.· The apps are stored in the file system as a memory image of the app object.· I prefix the memory image with the four ascii characters "Exec" to·distinguish apps files from other·files.· The app files are created by building a version of cdos with the app, and then using the appsave command to store it as a file.· After I created the sample apps hello, echo and clock I had to use the dumpf command to print out the hex codes, and then manually create the default app which writes the app files on a new file system.
This is a tedious and manual process, and· I'll have to figure out a way to automate this by transferring the files from the host computer somehow.
cdos currently uses a small area of memory used by the default app to load and run apps from the file system.· I allocate 200 longs for the stack and the malloc heap follows immediately after the stack to the end of RAM.· I'm going to change this so that the malloc heap will sit in between the cdos object and the clib object.· This will allow me to run larger apps that are as large as the heap space.
One limitation of spin code is that it can only call methods in other objects that are at a higher address.· They can never reference an object at a lower address.· This is because object offsets must always be positive.· They can never be negative.· I've tried, and it doesn't work if they're negative.· I am guessing that the spin interpreter doesn't mask of the address to 16 bits when adding an offset.· Therefore, a negative 16-bit offest will actually produce a 17-bit address when added to a 16-bit address.
Moving the malloc heap and keeping the app space between the cdos object and the rest of the code will allow this to work.
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cheers ... brian riley, n1bq, underhill center, vermont
The Shoppe at Wulfden
www.wulfden.org/TheShoppe/
www.wulfden.org/TheShoppe/prop/ - Propeller Products
www.wulfden.org/TheShoppe/k107/ - Serial LCD Display Gear
This is a nice effort especially for small utilities that can be run without rebooting the Propeller for reloads. Make a shell interface for scripting and you get lots of flexibility. I suppose you've looked at how some of the other boot-loaders work too; they need to reboot after loading each application to get back to the "O/S" prompt, but complete unmodified spin programs can be launched like that.
Thanks for contributing your efforts here.
--Steve
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
May the road rise to meet you; may the sun shine on your back.
May you create something useful, even if it's just a hack.
Thanks for the comments.· I am aware of some of the boot-loaders that reboot after loading.· That approach is probably the more effective way to reload programs.· C-DOS is more of a test program for the EEPROM file system than a real OS.· However, I found it intriguing that I could splice in fragements of a spin program, and it actually works.· A hello world program takes less than 50 bytes as long as the OS is there to provide system services.
I'm·adding I/O redirection to the command line so that the standard input and output can be redirected to files.· This will add a lot more power to simple apps stored in the file system.· One problem I would like to solve is a way to efficiently transfer files between the Prop and a PC.· The approach I would like to take is to run an app on the PC that talks to the prop over a serial line.· It would provide a serial terminal similar to the Parallax Serial Terminal, but it would also allow the prop to access the PC's file system.· A simple message protocol could be used to pass file I/O information between the prop and the PC.· Unfortunately, it seems like Microsoft has made it difficult to write simple programs that talk to a serial port under Windows.
Dave
Cheers.
--Steve
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
May the road rise to meet you; may the sun shine on your back.
May you create something useful, even if it's just a hack.
I looked at OBC's PropDOS.· It's a good solution for dynamically loading Spin programs.
I recall seeing the thread about Rayman's Y-modem package.· I thought about using Windows Hyperterminal to download either ASCII text files, or hex dumps of binary files.· However, I'm still trying to figure out how to do my own Windows/DOS app that would work as a serial terminal/file server/time server for C-DOS on the prop.
I have done a little more work on C-DOS, and I have file redirection working.· I can type commands like "cat >file1", "cat file1 file2 >file3" and "cat <file1 >>file2".· This all works OK.· I did find a bug in the clib memcpy function.· memcpy will use either bytemove, wordmove or longmove depeding on the the memory alignment of the pointers and the byte count.· However, when I use wordmove or longmove I neglected to divide the byte count by 2 or 4.· This means I was coping either 2 times or 4 times the number of bytes that I should have.· Needless to say, funny things were happening.· I'll fix that in the next version of clib in a few days.
Dave
Andy's PropTerminal may also be able to do some of the PC side.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
Thanks,
Dave
Re "One problem I would like to solve is a way to efficiently transfer files between the Prop and a PC. The approach I would like to take is to run an app on the PC that talks to the prop over a serial line. It would provide a serial terminal similar to the Parallax Serial Terminal, but it would also allow the prop to access the PC's file system. A simple message protocol could be used to pass file I/O information between the prop and the PC. Unfortunately, it seems like Microsoft has made it difficult to write simple programs that talk to a serial port under Windows.
This can be done. First step is to write a program that can talk to the serial port. vb.net can do this and you can either start from a blank vb.net program and write some very simple code to output a byte and read a byte back and then build it from there, or you can take a complicated bit of working code and try to find the bits in it that do what you want to do. If you are ok being overwhelmed with code see my link at the bottom of this post, scroll down to just above the first picture and there is the text " 2) An IDE written in free vb.net for writing software (C, Basic, Assembly), easy file transfers etc". Click on the IDE to get the complete vb.net source. I presume you can get hold of vb.net as well (it is a free download).
There are a number of ways to talk to the serial port - I've gone for a Timer and then poll the port regularly. This interfaces with a terminal screen. This program has grown like topsy, but what it can do is write/compile/download a 'hello world' in C or Basic or Assembly with one keypress and get that running on a propeller. You can then view the output on both a local screen and on a terminal screen on the PC as part of this program.
But what I think might interest you is the code for the file transfer protocol. I've gone for xmodem rather than ymodem as the code is small and simple. I've coded xmodem in both vb.net and sbasic and I also have the Z80 assembly version and it is a protocol both simple enough to understand and also to write code for in multiple languages. However, what I don't have is xmodem written in spin or pasm (as it is easier to run it in z80 assembly using an emulation on a propeller). So if you want xmodem for file transfers the PC side is written but not the spin side.
In practice using the code is extremely easy. Select 'download', browse to a file and click 'ok'. The file is then transferred to the propeller and stored on an sd card (or in your case, you would store to eeprom). Or you can transfer a file from the propeller back to the PC.
Of course the ultra simple way of transferring data is just to dump it out the serial port. But the problem is that whatever is receiving the bytes needs to know what is the start, and what is the end and what to call that file. xmodem is one step up from that. You send some bytes "XMODEM R MYFILE.TXT" and then carriage return, and that runs the xmodem program, R tells it to Receive, and then the name of the file you want to call this. Xmodem has some other features too, like timing out if nothing is sent, and sending data in packets with a checksum, a 'finish' packet and also is a protocol you can find in most terminal programs.
xmodem and ymodem are rather similar (xmodem sends files one at a time, ymodem can do groups of files, xmodem needs the filename set manually, ymodem includes it in the first data block) so if there is already ymodem code out there for the propeller it would make things a lot easier.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 4/15/2010 5:21:51 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
I'm fairly sure that I've called objects that have a lower address in DOL. You may even see this behaviour in standard spin programs because of how the compiler works.
VAR space is easy, you can get the size required by doing some maths on the object header, have a look at DOL. If you have any questions just ask, I'd write more now but it's past my bedtime and I have to work tomorrow [noparse]:([/noparse]
Steven
Cluso99, I'll look at the Sphinx PC C program.· That might be a good starting point for what I want to·ultimately do.
Steven, can you verify whether objects can call other objects at a lower address?· It appears to me that the Prop tool arranges the objects in order so that they can always call objects at a higher address.· As far as I can tell there can never be three objects that reference each other, such as A references B, B reference C and C references A.· There would be no way to order them so they always call a higher address.
MainObject
|-fsrw
|-SomeotherObject
|-fsrw
In this case SomeOtherObject calls fsrw which has a lower address than SomeOtherObject. I'm also pretty certain that I was also using loading programs with DOL that were then calling DOL again to load other objects.
However, I just checked some of my DOL2 code and I was calling DOL from an object that I loaded during runtime so it is possible to call another object with a lower address.
Here is the code from the interpreter. I've removed the bits that don't relate to a standard object call and unrolled the loop. How Chip managed to come up with this I don't know...
Okay, the bits I've bolded are where the addition to the object and variable bases occur. In all these cases the two values have been seperated out so overflow from one to the other can't happen. If a two's complement negative number is for the offset in the object table than everything will work as expected and you can call an object lower in memory.
edit: I had the shift the wrong way in the comments.
Therefore, negative offsets should work.· For some reason my initial tests failed, but I think I failed to fix up all the offsets in the relocated object.· I'll try it again to see if it works.
I tried the negative offsets again, and I got it to work OK.· This simplyfies things a lot.· I use the same technique that you use in the DOL by allocating a·block of memory and copying the object into the malloc'ed block.· After the app returns I free up the memory block.· I still haven't added a VAR block.· I need to study your solution some more so I fully understand it.
Thanks for help.
Dave