Shop OBEX P1 Docs P2 Docs Learn Events
GCC usage? - Page 4 — Parallax Forums

GCC usage?

124»

Comments

  • ersmithersmith Posts: 6,053
    edited 2015-04-19 15:40
    Yes though you can overwrite the area used by the PASM code, as you know exactly where it is (eg if PASM starts at MyPasm you know that from @MyPasm to the end of the code can be overwritten, and used for many things). There does not seem to be a simple way to get the address of the COG code, otherwise it would be a no brainner to simply typecast the address to an appropriate pointer type and use it.

    You have to know the address of the COG code in the HUB in order to call cogstart() with it. If you're using a binary blob in an array, well, then the code is in that array. If you're relying on the linker's magic COGC symbols, then the code is in an array called __load_start_foo_cog[] (where "foo" is the COGC section name, which if you're using the methods in the examples will be the same as the file name). There's also a symbol __load_stop_foo_cog[] which will indicate the memory just after that section. If you declare them both as extern char arrays (probably a good idea) then the size is __load_stop_foo_cog - __load_start_foo_cog.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-19 17:59
    ersmith wrote: »
    You have to know the address of the COG code in the HUB in order to call cogstart() with it. If you're using a binary blob in an array, well, then the code is in that array. If you're relying on the linker's magic COGC symbols, then the code is in an array called __load_start_foo_cog[] (where "foo" is the COGC section name, which if you're using the methods in the examples will be the same as the file name). There's also a symbol __load_stop_foo_cog[] which will indicate the memory just after that section. If you declare them both as extern char arrays (probably a good idea) then the size is __load_stop_foo_cog - __load_start_foo_cog.
    You can NOT call cogstart, that is the whole problem. It is not there, and it does not process the macro, it does not use the library at all, not running from COG code, this is the problem.

    I attempt to use anything like that from COGC and it does not work. I would like to get the entire program in COGC (6 cogs worth), with that is WITHOUT LMM or CMM.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-19 18:36
    You can NOT call cogstart, that is the whole problem. It is not there, and it does not process the macro, it does not use the library at all, not running from COG code, this is the problem.

    I attempt to use anything like that from COGC and it does not work. I would like to get the entire program in COGC (6 cogs worth), with that is WITHOUT LMM or CMM.
    You have to use cognew or coginit to load a separately compiled COG driver. The cogstart function just starts another copy of the LMM or CMM kernel in a separate COG and tells it to run the function whose address you pass as a parameter to cogstart. In that case, the COG image you're loading is the image of the LMM or CMM kernel and the space can't be reused. This doesn't happen in Spin because the Spin VM is in ROM. This is the one big advantage that Spin has over C, it's VM is in ROM and doesn't waste 2K of hub memory. This issue is somewhat resolved by the default branch of propgcc where Eric has implemented code to clone the LMM or CMM kernel running in COG 0 to start other COGs running LMM or CMM code. However, this is at the cost of requiring 2K of stack space for the cloning process.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-19 18:55
    David Betz wrote: »
    You have to use cognew or coginit to load a separately compiled COG driver. The cogstart function just starts another copy of the LMM or CMM kernel in a separate COG and tells it to run the function whose address you pass as a parameter to cogstart. In that case, the COG image you're loading is the image of the LMM or CMM kernel and the space can't be reused. This doesn't happen in Spin because the Spin VM is in ROM. This is the one big advantage that Spin has over C, it's VM is in ROM and doesn't waste 2K of hub memory. This issue is somewhat resolved by the default branch of propgcc where Eric has implemented code to clone the LMM or CMM kernel running in COG 0 to start other COGs running LMM or CMM code. However, this is at the cost of requiring 2K of stack space for the cloning process.
    That still does not tell me how to do it without any lmm or cmm code running at all in any cog. I do thank you though, for attempting to answer the question.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-19 19:28
    That still does not tell me how to do it without any lmm or cmm code running at all in any cog. I do thank you though, for attempting to answer the question.
    Try this:
    #include <propeller.h>
    
    _COGMEM uint32_t mask;
    _COGMEM uint32_t ticks;
    
    _NAKED void main(void)
    {
        mask = 1 << 16;
        ticks = CLKFREQ / 4;
        
        DIRA |= mask;
        
        for (;;) {
            OUTA ^= mask;
            waitcnt(CNT + ticks);
        }
    }
    
    Build it with this command:
    propeller-elf-gcc -Os -mcog -o blinker.elf blinker.c
    
    And run it on a QuickStart board with this command:
    propeller-load blinker.elf -r
    
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-19 19:34
    David Betz wrote: »
    Try this:
    #include <propeller.h>
    
    _COGMEM uint32_t mask;
    _COGMEM uint32_t ticks;
    
    _NAKED void main(void)
    {
        mask = 1 << 16;
        ticks = CLKFREQ / 4;
        
        DIRA |= mask;
        
        for (;;) {
            OUTA ^= mask;
            waitcnt(CNT + ticks);
        }
    }
    
    Build it with this command:
    propeller-elf-gcc -Os -mcog -o blinker.elf blinker.c
    
    And run it with this command:
    propeller-load blinker.elf -r
    
    OK, and then I guess I would be able to start other COG's using coginit() or cognew()?

    And I should magically know where in HUB memory to load the other cogs from??
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-19 19:37
    OK, and then I guess I would be able to start other COG's using coginit() or cognew()?

    And I should magically know where in HUB memory to load the other cogs from??
    You can create a main COG program and use it to launch other COG programs whose images you link with the main one. I'm working on an example and will post it when it's done. When all of the COGs are loaded, you can reuse all of hub memory for whatever you want.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-19 19:44
    David Betz wrote: »
    You can create a main COG program and use it to launch other COG programs whose images you link with the main one. I'm working on an example and will post it when it's done. When all of the COGs are loaded, you can reuse all of hub memory for whatever you want.
    Ok thank you. I am actually impressed with how well the C implementation is done for the propeller, given the strange architecture (from the point of view of how C works).

    This should simplify the issue for sure, I am hoping that globals are still in hub ram :), I know they are unless specified otherwise, just a smile.

    Thank you much for your help in getting me going with GCC on the propeller, it is a bit different than other platforms for some things.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-19 19:48
    Ok thank you. I am actually impressed with how well the C implementation is done for the propeller, given the strange architecture (from the point of view of how C works).

    This should simplify the issue for sure, I am hoping that globals are still in hub ram :), I know they are unless specified otherwise, just a smile.

    Thank you much for your help in getting me going with GCC on the propeller, it is a bit different than other platforms for some things.
    In what ways is it different other than the obvious differences imposed by the Propeller architecture itself like multiple COGs?
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-19 19:55
    David Betz wrote: »
    In what ways is it different other than the obvious differences imposed by the Propeller architecture itself like multiple COGs?
    Jsut the considerations of compilation related to multiple cogs of limited size. The language is identical, hence why I am impressed at the implementation.

    Let me know once you get the multi cog, cog mode example done, I am very curious how that is done. And thank you for taking the time to do so.
  • jazzedjazzed Posts: 11,803
    edited 2015-04-19 22:28
    If you only want to integrate PASM with Propeller GCC, it can't get much simpler than this.

    Just copy/paste the BlinkPasm.c file into a new project, and add blink.spin to the project.
    /**
    * This is the main BlinkPasm.c program file.
    */
    
    #include "simpletext.h"
    
    volatile int pin = 26;
    
    int main(void)
    {
       extern int binary_blink_dat_start[];
       cognew(binary_blink_dat_start, &pin);
    
       printi("Now blinking on pin %d.\n", pin);
       while(1);
       return 0;
    }
    
    ' 
    ' blink.spin
    '
    
    PUB one_pub_required_by_spin
    
    DAT
      blink org 0
       mov blink, #1 ' set blink bit, and shift
    led
      rdlong led, par
      shl blink, led ' shift left by led
    time
       or DIRA, blink ' set to output
    delay
       rdlong time, #0
       shr time, #2 ' delay clock cnt/4
       mov delay, time
       add delay, CNT
    :loop
       xor OUTA, blink ' blink led
       waitcnt delay, time wr
       jmp #:loop
    
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-22 20:20
    jazzed wrote: »
    If you only want to integrate PASM with Propeller GCC, it can't get much simpler than this.

    Just copy/paste the BlinkPasm.c file into a new project, and add blink.spin to the project.
    /**
    * This is the main BlinkPasm.c program file.
    */
    
    #include "simpletext.h"
    
    volatile int pin = 26;
    
    int main(void)
    {
       extern int binary_blink_dat_start[];
       cognew(binary_blink_dat_start, &pin);
    
       printi("Now blinking on pin %d.\n", pin);
       while(1);
       return 0;
    }
    
    ' 
    ' blink.spin
    '
    
    PUB one_pub_required_by_spin
    
    DAT
      blink org 0
       mov blink, #1 ' set blink bit, and shift
    led
      rdlong led, par
      shl blink, led ' shift left by led
    time
       or DIRA, blink ' set to output
    delay
       rdlong time, #0
       shr time, #2 ' delay clock cnt/4
       mov delay, time
       add delay, CNT
    :loop
       xor OUTA, blink ' blink led
       waitcnt delay, time wr
       jmp #:loop
    
    Huh, thank you for that, I would have never guessed that one.

    How does that translate to using COGC, instead of asm?
Sign In or Register to comment.