Examples of an XMMC program starting COG C?
photomankc
Posts: 943
Well, I'm excited. My first class got off the ground today and started blinking LEDs in C++! Woot! So thinking about what I need to get going to make my Robot work with C++ code:
I need to port my 400KHz I2C driver over to COG C. The driver is designed to allow multiple COGs through locks to access multiple parts over the same two wires and my motor driver, Ultrasonics, and Navigation sensors all live there.
I need to port the Ultrasonic sampling/filtering driver over to COG C and same will be true for the Accelerometer/Compass driver.
Those are subsytems that have to run in thier own cog because of timing issues and to keep the over-all robot responsive. I'm looking for any example (C++ based would be great) of how to go about starting a new COG running COG C from the main XMMC program. Since SimpleIDE compiles the whole project based on the setting for the project file I'm guessing the COG C must be compiled seperate and then somehow linked into the XMMC program in it's compiled form? Am I thinking in the right direction at least?
I appologise in advance if these are noob questions. I was always pretty decent with the syntax, logic, and structure of C++ but the includes, DEFINES, and compiler incantations always seem to eat my lunch once the project gets big.
I need to port my 400KHz I2C driver over to COG C. The driver is designed to allow multiple COGs through locks to access multiple parts over the same two wires and my motor driver, Ultrasonics, and Navigation sensors all live there.
I need to port the Ultrasonic sampling/filtering driver over to COG C and same will be true for the Accelerometer/Compass driver.
Those are subsytems that have to run in thier own cog because of timing issues and to keep the over-all robot responsive. I'm looking for any example (C++ based would be great) of how to go about starting a new COG running COG C from the main XMMC program. Since SimpleIDE compiles the whole project based on the setting for the project file I'm guessing the COG C must be compiled seperate and then somehow linked into the XMMC program in it's compiled form? Am I thinking in the right direction at least?
I appologise in advance if these are noob questions. I was always pretty decent with the syntax, logic, and structure of C++ but the includes, DEFINES, and compiler incantations always seem to eat my lunch once the project gets big.
Comments
Yes, you're thinking in the right direction.
Unfortunately linking COG C programs with XMMC mode doesn't seem to work right now :sick:
PASM works fine with LMM/XMMC and COG C works fine with LMM.
We're looking into the XMMC COG C problem.
--Steve
Thanks for all the hard work Steve, and the rest of you guys working on it.
Everything else works except for that.
I've attached a SimpleIDE example for Quickstart boards.
Set Memory mode to LMM to see the correct behavior.
@photomankc I'll post a C++ version after we figure this out. Sorry for the trouble.
I've been digging through the PropBOE examples on I2C and think I'm finally getting my head around it a little bit. I see there is already a pretty nice implementation of the bus in there. I plan to try and write my own using that as a basic guide.
For those who have clones of the propeller-gcc repository, do a cycle of pull, update, and build.
All fixes will be in official beta package updates when the time comes, meanwhile I'll provide some new propeller-gcc only packages for testing once builds are done.
Thanks,
--Steve
Eric
If I failed to be clear, please mention it here.
Some program notes:
1) If you want to run this in LMM mode, the libtiny.a file can be included and the program will be < 8KB
2) If you remove the _FullDuplexSerialDriver code just above main (and use libtiny.a) the program will be < 4KB
3) The program includes Eric's suggestion for XMMXC work-around. You should not need a new compiler.
4) The libtiny.a library is not compiled for XMMC. libtiny.a is compiled for LMM only and will cause failures with other memory models.
[Running to lunch to play with my Quickstart]
EDIT: I think the comments are very clear and easy to follow. This will be a great template for me to follow in writing out some simple drivers for my hardware to operate in XMMC mode.
I seem to have correctly surmized that they are based on the file name of the COG C program, and I'm guessing they are derived from the size of the code the compiler produces, thus the 'extern' keyword?
Compiles and runs great as LMM or XMMC either way.
Nice work. Looks like you've done this before
For LMM mode, you can add libtiny.a to your project and it will "significantly" reduce the code size. It won't work with XMM modes though.
We've talked about making a GCC compressed mode - that was first proposed back in February I think. It would theoretically chop a GCC binary in half at the cost of some performance loss. It's just a matter of time before this happens.
I remember you mentioning the libtiny thing. I'll have to try that and see what it chops off the ~3100 bytes LMM produced.
GCC compressed sounds interesting. The SPIN/PASM program was like 180 bytes where the XMMC was about 3200 so cutting that to 1600 or so would be a nice thing if the performance hit is not too massive.
Thanks for the help getting over the platform hump!
-Kyle
If you're already down to 3KB, the libtiny thing won't help too much.
Indeed, the kernel will be close to 1.5KB on its own.
If it's really tiny code you're looking for, try compiling in COG mode with -mcog. That may let you fit the whole thing in COG memory (no LMM or XMM at all).
I know my project is going to exceed the 32KB boundry in code/data so I'm fine with it. XMMC with FLASH will run faster, but... and it's a big but, my sensors were all desinged around a fast I2C bus and several SPIN cogs shareing that bus. That's not viable with XMMC. I can run the bus in COG C but only the main program COG is going to be able to access that bus through any kind of class interface. Unless something really creative hits me.
Another approach is to integrate many peripheral services into the bus driver which by its nature reduces access locking requirements. I haven't done the multi-service thing in COG C, but do have a PASM driver that serves up to 4 different devices: Accelerometer, ADC, RTC, and EEPROM.
What I have done thus far used locks in the SPIN object to lock the bus when a cog calls StartBit and unlock with StopBit and several convenience functions to string it all together from the primitives for byte, word, long, and block.