Newbie Trouble With Running Multiple Cogs
dchokola
Posts: 8
I'm a newbie trying to get my head around some interesting behavior with propgcc/SimpleIDE. I've been working on trying to make a nice, generalized set of functions for a producer-consumer model where one cog can produce data, load it into the hub RAM, and another cog can then take the data in. I think that code makes sense, but when I try to launch a cog containing the consumer (or producer, it doesn't matter) from cog 0, I get no love. Frustrated and ready to throw my computer out of a window, I went back to the toggle demo included with SimpleIDE. Here's what I found using the cog_c_toggle code:
- It works just fine, as-is, so I wanted to see how easily I could recreate some of the same issues I saw with my producer-consumer program.
- It won't build in COG memory model!
- The linker can't find a reference to _sleep. Why?
- The linker ignores -ltiny for COG mode, but that's not the problem. Go ahead and add -ltiny to the "Other Linker Options" in SimpleIDE.
- Replaced sleep(2) in toggle.c for waitcnt(_clkfreq*2 + CNT) and it's all better again, and running in COG mode. Yay! :cool:
- Added #include and a printf statement to toggle_fw.cogc. It's broken again!
-
propeller-elf-gcc -r -Os -mcog -o toggle_fw.cog -xc toggle_fw.cogc
-
`__clkfreq' referenced in section `.text' of /opt/parallax/lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/lib/libcog.a(cogserial.o): defined in discarded section `.boot' of /opt/parallax/lib/gcc/propeller-elf/4.6.1/spinboot.o
- Removing printfs and #include from toggle.c made no difference. I understand that printfs from two or more running cogs can be a problem.
- No combination of optimization flags or memory model made a difference.
- The problem can be recreated just as easily by adding _OUTA = _clkfreq instead of a printf, say.
-
What is going on here?I'm finding documentation on what the compiler and linker are really doing here and just exactly what a .cogc file is are pretty lacking. https://code.google.com/p/propgcc/wiki/PropGccInDepth has a lot of interesting and important info, but it talks about .cogc files as if I'm supposed to already know what they are, and I can't find mention of them elsewhere in the documentation.
Running propeller-elf-gcc (propellergcc_v0_3_5_1622) 4.6.1.
Comments
In your own code you can get around this by doing: but that doesn't help with libraries that are already compiled, unfortunately.
.cogc isn't really intended for the main program -- it was primarily imagined as being for drivers, and so the libraries available in COG mode are very limited (and unfortunately not as well tested, which is why you're running in to bugs like that). It's probably best not to try to do printing from a .cogc file; in fact it's probably best not to rely on too many libraries at all in .cogc files. The main libraries are best used from the HUB mode main program, and the COGs can send requests to that main program to do things (like printing) on their behalf.
As to what exactly a .cogc file is: it's a .c file that will be compiled to be loaded and run in a COG by the main (usually LMM or XMM) program. Because COG and LMM modes are different and the code is not compatible, some linker magic is required to allow these two different kinds of C programs to co-exist. SimpleIDE recognizes the .cogc extension and does the magic as best it can. But this is a bit tricky, and so sometimes the magic fails (i.e. there are bugs). Sorry about that!
Eric
A .cogc file is compiled so that its code is placed in a separate section (something like .foo.cogc) instead of in the normal .text section. As long as each .cogc section fits in 2K everything will be all right. Note, though, that if you link libraries with the .cogc code each individual .cogc section will have to have a complete copy of the library (so if you use 1K worth of library in the .cogc, and have 8 of them, then you'll use up 8K of space for the same library repeated 8 times).
For the situation you're describing it might make things easier to have the coordinating cog run in LMM mode -- then it can be as large as you like and can do fancy things like printf. The worker cogs would be .cogc code that's designed to be as small as possible. Note that .cogc files are always compiled in COG mode, regardless of the project settings (so the project as a whole could be LMM mode with the workers still compiled in COG mode).
I'm not sure it's exactly the forums fault. I have had that issue with Chrome from the Debian package and also the Konqueror browser in Debian.
On the other hand FireFox and Chrome downloaded from Google on Debian have been fine.
Any way I do wish Parallax would find a work around for that issue.
Running one cog in LMM mode is not a showstopper for me. I was just curious why the compiler acted differently when in COG mode or LMM (missing references to _sleep or _clkmode). I've got pretty frustrated the other day and gave up, but I've got a good idea how to proceed the next time I have some free time to experiment. I did manage to build the latest Mercurial versions of PropGCC and SimpleIDE, at least.
Running Chromium on Debian here. I guess that might explain it.