Shop OBEX P1 Docs P2 Docs Learn Events
Examples of an XMMC program starting COG C? — Parallax Forums

Examples of an XMMC program starting COG C?

photomankcphotomankc Posts: 943
edited 2012-07-13 14:58 in Propeller 1
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.

Comments

  • jazzedjazzed Posts: 11,803
    edited 2012-07-09 13:59
    photomankc wrote: »
    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?

    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
  • photomankcphotomankc Posts: 943
    edited 2012-07-09 16:22
    Bummer, I guess I'll just sit tight till that is working. In the mean time I guess I can get to work on the translation from PASM to C. I can get things working in LMM and it should be good to go later for XMMC.

    Thanks for all the hard work Steve, and the rest of you guys working on it.
  • KyeKye Posts: 2,200
    edited 2012-07-09 19:41
    That shouldn't be a hard problem to fix. Assuming the COG gets compiled into an object who's addresses are not globally linked... it should just be a binary blob. I'm guessing its the fact that you need to load it into memory all at once to boot is the problem?
  • jazzedjazzed Posts: 11,803
    edited 2012-07-09 21:51
    Kye wrote: »
    That shouldn't be a hard problem to fix. Assuming the COG gets compiled into an object who's addresses are not globally linked... it should just be a binary blob. I'm guessing its the fact that you need to load it into memory all at once to boot is the problem?
    Key, there is a subtle problem somewhere causing serial IO to stop after doing a COG C cognew.
    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.
  • photomankcphotomankc Posts: 943
    edited 2012-07-09 23:02
    Don't be sorry man! I know you have a full plate of stuff going on and I'm very grateful for your time in answering this.


    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.
  • jazzedjazzed Posts: 11,803
    edited 2012-07-10 12:55
    We identified the XMMC runtime issue this morning and a fix is pushed.

    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
  • ersmithersmith Posts: 6,096
    edited 2012-07-10 15:12
    A work around for those who do not want to build from the repository is to add:
    extern unsigned int _C_LOCK;
    _C_LOCK |= 256;
    
    right at the start of your main() function (before trying to start any other cogs). This will set a flag that indicates to the COGs that they do not have to initialize memory. The XMM kernel was missing this statement, and as a result the COG C code was re-initializing RAM.

    Eric
  • jazzedjazzed Posts: 11,803
    edited 2012-07-11 00:43
    As promised, here is a C++ version that runs XMMC and starts a COG C program. It is essentially the same as one of the earlier cog_c_toggle programs except that it uses a Class to encapsulate all the toggling stuff. I've tried very hard to comment the code so that it could be easy for beginners to understand.

    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.
  • photomankcphotomankc Posts: 943
    edited 2012-07-11 07:28
    Did you forget the attachment? :)
  • jazzedjazzed Posts: 11,803
    edited 2012-07-11 08:03
  • photomankcphotomankc Posts: 943
    edited 2012-07-11 09:21
    Awsome! Thanks so much for that!

    [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.
  • photomankcphotomankc Posts: 943
    edited 2012-07-11 23:45
    Jazzed. Thanks a ton for that reference. I was able to bang out a COG C driver for the touch buttons tonight based on the example you provided and get that working under LMM and XMMC. I did have a question though. What are these:
    extern uint32_t _load_start_TouchBtns_cog[];
    extern uint32_t _load_stop_TouchBtns_cog[];
    

    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?
  • photomankcphotomankc Posts: 943
    edited 2012-07-12 11:32
    Alright, my first attempt to port one of my custom driver objects over to C++. It works but I do miss that easy INA[0..7] OUTA[8..15] stuff from SPIN. Definately a good work-alike to the SPIN/PASM object I had but wow, the code do get big really quick.

    Compiles and runs great as LMM or XMMC either way.
  • jazzedjazzed Posts: 11,803
    edited 2012-07-12 12:09
    photomankc wrote: »
    Alright, my first attempt to port one of my custom driver objects over to C++. It works but I do miss that easy INA[0..7] OUTA[8..15] stuff from SPIN. Definately a good work-alike to the SPIN/PASM object I had but wow, the code do get big really quick.

    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.
  • photomankcphotomankc Posts: 943
    edited 2012-07-12 12:30
    Yeah, I lived C++ for a while in college and did a bit of PC programming with it afterwards, but I'm rusty like an old Ford truck in it now. I see a couple places where I have to be more careful with = and OUTA/DIRA that's where SPIN spoils you as well as simple repeat loops.

    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
  • jazzedjazzed Posts: 11,803
    edited 2012-07-12 15:00
    photomankc wrote: »
    I remember you mentioning the libtiny thing. I'll have to try that and see what it chops off the ~3100 bytes LMM produced.

    If you're already down to 3KB, the libtiny thing won't help too much.
  • ersmithersmith Posts: 6,096
    edited 2012-07-12 19:45
    jazzed wrote: »
    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).
  • photomankcphotomankc Posts: 943
    edited 2012-07-12 20:27
    Well duh! You are right, I was not thinking of the LMM kernel in that total. I'm not really after super-small code, just was a bit surprised at the final tally. Really SPIN gets to cheat a bit because you don't have to plug it's kernel into the EEPROM to run the code it gets it for free from ROM so if I tack the SPIN Interpreter into the final tally it's not THAT bad.

    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.
  • jazzedjazzed Posts: 11,803
    edited 2012-07-13 09:58
    photomankc wrote: »
    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.
    Why can't you have other COG C programs access the bus driver via the mailbox?

    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.
  • photomankcphotomankc Posts: 943
    edited 2012-07-13 14:58
    I guess I could... I'd need the mailbox to have a place for all the details so I could say what address, read/write, what register, and the data buffer. The COG C would need to a bit smarter so it could string that all together as a full START -> STOP transaction rather than what I have now which is very small primitives. I'd just not have the nice OOP style interface.

    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.
Sign In or Register to comment.