Shop OBEX P1 Docs P2 Docs Learn Events
Newbie Trouble With Running Multiple Cogs — Parallax Forums

Newbie Trouble With Running Multiple Cogs

dchokoladchokola Posts: 8
edited 2014-01-08 14:24 in Propeller 1
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:
  1. 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.
  2. 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.
  3. Replaced sleep(2) in toggle.c for waitcnt(_clkfreq*2 + CNT) and it's all better again, and running in COG mode. Yay! :cool:
  4. 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

  • ersmithersmith Posts: 6,054
    edited 2014-01-04 14:30
    There's a bug in the handling of the CLKFREQ variable that you're running into. This is fixed in the current source code, but there hasn't been a SimpleIDE release based on that yet (it takes a while for everything to be vetted and get tested). The bug prevents CLKFREQ accesses in .cogc files, either directly or indirectly (you're getting it indirectly from the cog serial functions, which work OK with a simple COG mode .c but not with a .cogc linked with another file).

    In your own code you can get around this by doing:
    #include <propeller.h>
    #undef CLKFREQ
    #define CLKFREQ (*(int *)0)
    
    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
  • dchokoladchokola Posts: 8
    edited 2014-01-04 14:59
    @ersmith,Thanks for the quick reply. I guess I'll go clone the mercurial tree and try a more recent version and see what I can duplicate there. I can confirm that redefining _clkfreq/CLKFREQ does the trick in my own code, at least.Now for a little more background and another question. I envisioned a system with one coordinating cog and several worker cogs, passing data back and forth through the hub. Worker cogs won't really need to communicate with one another. There could be a transmit cog, a receive cog, sensor cogs, a motor control cog, and some coordinating cog that takes data from the receiver and sensors and sends processed data/commands to the transmitter and motor cogs. All of the cogs would only need to worry about one thing and would work in parallel, asynchronously. Because each cog performs only a simple task, there's no need for other memory models and COG mode could be used, keeping the code fast.I noticed that using a plain .c file (instead of a.cogc file) and running cognew(...) to start a function makes the build Smile out because it thinks my code is too big. .cogc files seem to have some sort of magic that lets the build tools understand that it will be loaded into a separate cog and going over 2kB program size doesn't necessarily mean I have to use LMM or somesuch. Say I have a program that compiles down to a 1kB routine for each cog and runs on all 8 cogs, can I use COG mode even though the compiled code is 8kB in hub RAM or am I stuck using LMM or XMM*?Thanks again,Dan
  • dchokoladchokola Posts: 8
    edited 2014-01-04 15:01
    The forum keeps squashing my text down; please excuse the formatting. I can't seem to edit it, either.
  • ersmithersmith Posts: 6,054
    edited 2014-01-05 13:51
    dchokola wrote: »
    I envisioned a system with one coordinating cog and several worker cogs, passing data back and forth through the hub. Worker cogs won't really need to communicate with one another. There could be a transmit cog, a receive cog, sensor cogs, a motor control cog, and some coordinating cog that takes data from the receiver and sensors and sends processed data/commands to the transmitter and motor cogs. All of the cogs would only need to worry about one thing and would work in parallel, asynchronously. Because each cog performs only a simple task, there's no need for other memory models and COG mode could be used, keeping the code fast.I noticed that using a plain .c file (instead of a.cogc file) and running cognew(...) to start a function makes the build Smile out because it thinks my code is too big. .cogc files seem to have some sort of magic that lets the build tools understand that it will be loaded into a separate cog and going over 2kB program size doesn't necessarily mean I have to use LMM or somesuch. Say I have a program that compiles down to a 1kB routine for each cog and runs on all 8 cogs, can I use COG mode even though the compiled code is 8kB in hub RAM or am I stuck using LMM or XMM*?Thanks again,Dan

    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).
  • Heater.Heater. Posts: 21,230
    edited 2014-01-07 01:32
    dchokla,
    The forum keeps squashing my text down

    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.
  • dchokoladchokola Posts: 8
    edited 2014-01-08 14:24
    ersmith wrote:
    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).

    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.
    heater wrote:
    I have had that issue with Chrome from the Debian package and also the Konqueror browser in Debian.

    Running Chromium on Debian here. I guess that might explain it.
Sign In or Register to comment.