Shop OBEX P1 Docs P2 Docs Learn Events
propgcc default branch, load_cog_driver_xmm is not found — Parallax Forums

propgcc default branch, load_cog_driver_xmm is not found

trancefreaktrancefreak Posts: 186
edited 2014-04-10 19:41 in Propeller 1
Hi all,

I try to start a .cogc program in XMMC mode using the latest propgcc default branch build Steve posted here:
https://drive.google.com/file/d/0BzcfH7bdVTbtNkRRbmE5TUVtTnM/edit?usp=sharing

When using load_cog_driver_xmm, the compiler throws an undefined reference error message.
propeller-elf-gcc.exe -v GCC 4.6.1 (propellergcc-alpha_v1_9_0_2408)
propeller-elf-gcc.exe -r -Os -mcog -o xmmc/IODriver.cog -xc IODriver.cogc
propeller-elf-objcopy --localize-text --rename-section .text=IODriver.cog xmmc/IODriver.cog
propeller-elf-gcc.exe -I . -L . -I mailbox -I IODriver -o xmmc/IOTest.elf -Os -mxmmc -Wall -m32bit-doubles -fno-exceptions -Dprintf=__simple_printf xmmc/IODriver.cog IOTest.cpp
IOTest.cpp: In function 'int main()':
IOTest.cpp:40:11: warning: unused variable 'cogId' [-Wunused-variable]
C:\Users\CHRIST~1\AppData\Local\Temp\ccyNXX1n.o: In function `start(void volatile*)':
(.text+0x20): undefined reference to `load_cog_driver_xmm(unsigned int*, unsigned int, unsigned int*)'
collect2: ld returned 1 exit status

Does load_cog_driver_xmm no longer exist in the default branch?
I found the following definition in the propeller.h source:
/**
 * @brief Load a COG driver
 * @param id The COG driver name
 * @param param Parameter to pass to the driver
 * @returns the id of the COG that was loaded
 */
#define load_cog_driver(id, param)                                      \
            load_cog_driver_xmm(                                        \
                binary_##id##_dat_start,                                \
                binary_##id##_dat_end - binary_##id##_dat_start,        \
                (uint32_t *)(param))
    
uint32_t *get_cog_driver_xmm(uint32_t *code, uint32_t codelen);
int load_cog_driver_xmm(uint32_t *code, uint32_t codelen, uint32_t *params);

Do I have to use load_cog_driver(id, param) when using the default branch? The syntax with this function is different. I have to provide an id but
I haven't found an example using the load_cog_driver function to load a .cogc program from another c program.

Does anyone have sample code how this is done or a solution to use the load_cog_driver_xmm function and get rid of the undefined reference compiler error message?

Any help is really appreciated :-)


Thanks,
Christian

Comments

  • ersmithersmith Posts: 6,054
    edited 2014-04-09 05:15
    I'm not sure why you got that error, but load_cog_driver_xmm is still in the default branch and hasn't changed as far as I can remember. It is only included in the libraries in XMM mode, though, which is why using the load_cog_driver() macro is better (that macro works in both XMM and non-XMM modes).
  • trancefreaktrancefreak Posts: 186
    edited 2014-04-09 05:26
    ersmith wrote: »
    I'm not sure why you got that error, but load_cog_driver_xmm is still in the default branch and hasn't changed as far as I can remember. It is only included in the libraries in XMM mode, though, which is why using the load_cog_driver() macro is better (that macro works in both XMM and non-XMM modes).

    Hi Eric,

    I had a look at the load_cog_driver_xmm function which just copies the code from xmm to an array in hub by using memcpy and then uses cognew. When I'm at home, I will try to do it that way because it looks like the xmm libraries are somehow missing in Steve's latest build.

    Just because of curiosity: Can the load_cog_driver() function also be used with cogc programs or only with spin programs having a DAT section (I'm assuming this only because I see binary_##id##_dat_start as identifier in the header file).

    If it can be used with .cogc programs, is there somewhere example code I can look at?

    Thanks,
    Christian
  • jazzedjazzed Posts: 11,803
    edited 2014-04-09 08:06
    Hi Eric,

    I had a look at the load_cog_driver_xmm function which just copies the code from xmm to an array in hub by using memcpy and then uses cognew. When I'm at home, I will try to do it that way because it looks like the xmm libraries are somehow missing in Steve's latest build.

    All the libraries seem to be in the package.
  • trancefreaktrancefreak Posts: 186
    edited 2014-04-09 08:47
    jazzed wrote: »
    All the libraries seem to be in the package.

    That's really interesting. I don't know why I get
    C:\Users\CHRIST~1\AppData\Local\Temp\ccyNXX1n.o: In function `start(void volatile*)':
    (.text+0x20): undefined reference to `load_cog_driver_xmm(unsigned int*, unsigned int, unsigned int*)'
    

    If I compile the same program with the release branch, the build succeeds.
    When I'm at home I will post a zip file containing the complete SimpleIDE project.

    If you have time, maybe you could try to build the project.

    Thanks,
    Christian
  • jazzedjazzed Posts: 11,803
    edited 2014-04-09 08:54
    Christian I'll do some testing now that I have a little time.

    Everyone please remember that the default branch alpha_1_9_2408 package is not released. I heard we may be running a test program with it before summer because Andy needs XMMC multi-cog capabilities.

    Thanks.
    That's really interesting. I don't know why I get
    C:\Users\CHRIST~1\AppData\Local\Temp\ccyNXX1n.o: In function `start(void volatile*)':
    (.text+0x20): undefined reference to `load_cog_driver_xmm(unsigned int*, unsigned int, unsigned int*)'
    

    If I compile the same program with the release branch, the build succeeds.
    When I'm at home I will post a zip file containing the complete SimpleIDE project.

    If you have time, maybe you could try to build the project.

    Thanks,
    Christian
  • jazzedjazzed Posts: 11,803
    edited 2014-04-09 09:19
    Ok,

    Here is a pasm project using propellergcc-alpha_v1_9_2408.

    The only differences between this and the repository is that it is built with SimpleIDE instead of make and this start() function changed a bit.
    // C stub function to start the PASM routine
    // need to be able to provide the entry point to the PASM
    // and a pointer to the STATIC HUB mailbox
    // the cognew function in the propeller.c library returns the COG #
    //
    int start(unsigned int *pinptr)
    {
        // The label binary_toggle_dat_start is automatically placed
        // on the cog code from toggle.dat by objcopy (see the Makefile).
        extern unsigned int binary_toggle_dat_start[];
        extern unsigned int binary_toggle_dat_end[]; // <+++++++++++++++ added +++++++++++++++>
        //return cognew(&binary_toggle_dat_start, pinptr); // commented
        return load_cog_driver(toggle,pinptr);  // <+++++++++++++++ added +++++++++++++++>
    }
    
    Build output looks like this:
    Project Directory: C:/gccdev/spinside/testcode/toggle/pasm_toggle/
    
    propeller-elf-gcc.exe -v GCC 4.6.1 (propellergcc-alpha_v1_9_0_2408)
    openspin.exe -c -o xmmc/toggle.dat toggle.spin
    Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2013 Parallax Inc. DBA Parallax Semiconductor.
    Compiled on Oct  9 2013
    Compiling...
    toggle.spin
    Done.
    Program size is 88 bytes
    propeller-elf-objcopy -I binary -B propeller -O propeller-elf-gcc --redefine-sym _binary_xmmc_toggle_dat_start=_binary_toggle_dat_start --redefine-sym _binary_xmmc_toggle_dat_end=_binary_toggle_dat_end --redefine-sym _binary_xmmc_toggle_dat_size=_binary_toggle_dat_size xmmc/toggle.dat xmmc/toggle_firmware.o
    propeller-elf-gcc.exe -I . -L . -o xmmc/toggle.elf -Os -mxmmc -fno-exceptions xmmc/toggle_firmware.o toggle.c
    propeller-elf-objdump -h xmmc/toggle.elf
    Done. Build Succeeded!
    
    Same for xmm-single and xmm-split except the folders and symbols are xmm_single or xmm_split instead of xmmc ... I.E.
    Project Directory: C:/gccdev/spinside/testcode/toggle/pasm_toggle/
    
    propeller-elf-gcc.exe -v GCC 4.6.1 (propellergcc-alpha_v1_9_0_2408)
    openspin.exe -c -o xmm_single/toggle.dat toggle.spin
    Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2013 Parallax Inc. DBA Parallax Semiconductor.
    Compiled on Oct  9 2013
    Compiling...
    toggle.spin
    Done.
    Program size is 88 bytes
    propeller-elf-objcopy -I binary -B propeller -O propeller-elf-gcc --redefine-sym _binary_xmm_single_toggle_dat_start=_binary_toggle_dat_start --redefine-sym _binary_xmm_single_toggle_dat_end=_binary_toggle_dat_end --redefine-sym _binary_xmm_single_toggle_dat_size=_binary_toggle_dat_size xmm_single/toggle.dat xmm_single/toggle_firmware.o
    propeller-elf-gcc.exe -I . -L . -o xmm_single/toggle.elf -Os -mxmm-single -fno-exceptions xmm_single/toggle_firmware.o toggle.c
    propeller-elf-objdump -h xmm_single/toggle.elf
    Done. Build Succeeded!
    
  • trancefreaktrancefreak Posts: 186
    edited 2014-04-09 09:31
    Hi Steve,

    Thanks for trying it out and attaching the project! :-)
    I will try to compile the project at home.
    But it looks like only load_cog_driver() is used instead of load_cog_driver_xmm().

    Christian
  • ersmithersmith Posts: 6,054
    edited 2014-04-09 09:38
    Just because of curiosity: Can the load_cog_driver() function also be used with cogc programs or only with spin programs having a DAT section (I'm assuming this only because I see binary_##id##_dat_start as identifier in the header file).

    If it can be used with .cogc programs, is there somewhere example code I can look at?
    Yes, it can be used with .cogc programs. See for example demos/toggle/cog_c_toggle, which uses load_cog_driver_xmm to load the toggle_fw.cog file if it's compiled with MODEL=xmmc.

    Regards,
    Eric
  • jazzedjazzed Posts: 11,803
    edited 2014-04-09 10:08
    Here is a functional example using cogc.

    Notice that in this example (and the other) load_cog_driver_xmm is used by a macro. In this case the equivalent cogc macro has been added.

    There is a problem with the simpletools print library for this example. Use printf which does proper locking.

    Another issue with the Simple Libraries seems to be some propeller-gcc branch incompatibility.

    /**
     * @brief Load a COGC driver
     * @param id The COGC driver name
     * @param param Parameter to pass to the driver
     * @returns the id of the COG that was loaded
     */
    #define load_cogc_driver(id, param) \
                load_cog_driver_xmm( \
                    _load_start_##id##_cog, \
                    _load_stop_##id##_cog - _load_start_##id##_cog, \
                    (uint32_t *)(param))
    
  • trancefreaktrancefreak Posts: 186
    edited 2014-04-09 11:12
    Thanks Steve and Eric for your help!
    Steve, both examples work. I will use them as reference implementation.

    I have attached the project I did which doesn't work. Maybe you have luck to find out, why it doesn't work ;-)

    Thanks again!
    Christian
  • jazzedjazzed Posts: 11,803
    edited 2014-04-09 17:28
    Well, there are a couple of issues in your project. The biggest one is not your fault though ;-)

    It looks like the only way to find the load_cog_driver_xmm function is by using a .c file.
    The forward declaration is not included in the propeller.h #ifdef cplusplus wrapper.
    If I move the propeller.h cplusplus wrapper to near the end of the file, then .cpp will work fine.

    Other issues:

    1. Stack not big enough. Should be: unsigned stack[EXTRA_STACK_LONGS + 16];

    static struct {
    unsigned stack[16];
    volatile ioDriverMailbox_t ioDriverMailbox;
    } ioDriverPar;

    2. Wrong symbol for load_cog_driver_xmm. That macro doesn't expand IODriver_code to _load_start_IODriver_code_cog.
    3. Also IODriver_code is not the right symbol for SimpleIDE, it's the same name as the file. You can always check these by doing Show Map File in the project manager.

    uint8_t start(volatile void *parptr) {
    extern uint32_t *IODriver_code;
    #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__)
    return load_cog_driver_xmm(IODriver_code, 496, (uint32_t *)parptr);
    #else
    return cognew(IODriver_code, parptr);
    #endif
    }
  • trancefreaktrancefreak Posts: 186
    edited 2014-04-10 00:42
    Hi Steve,

    Thanks very much for analyzing the project and finding all these issues.
    It was 2am in the morning when I put that all together so maybe I was more asleep than awake :-)

    I used the demos\toggle\cogc_toggle example as reference. There I saw this:
    /*
     * function to start up a new cog running the toggle
     * code (which we've placed in the toggle_fw.cog section)
     */
    void start(volatile void *parptr)
    {
        extern unsigned int *toggle_fw_code;
    #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__)
        load_cog_driver_xmm(toggle_fw_code, 496, (uint32_t *)parptr);
    #else
        cognew(toggle_fw_code, parptr);
    #endif
    }
    

    With regards to EXTRA_STACK_LONGS: Shouldn't that only be used when starting a cog in XMM mode where the XMM VM is executing the code from
    external memory? When a driver is copied and executed directly in the cog ram without any VM involved, I thought the stack size is only needed, when the code uses
    stack. The toggle cogc example also defines a stack size of 16 and should run in LMM and XMM mode.

    Yesterday evening I also noticed the issue with C++. Your example worked well until I switched to C++. Then it also stopped working with the unknown reference
    error message.

    So I ended up using a workaround instead of the load_cog_driver or load_cog_driver_xmm.
    I copy the code from xmm memory to an array and use cognew handing over the array. Works well.

    But the part with the stack size still puzzles me. Are you sure that such a big stack size (EXTRA_STACK_LONGS is > 1kbyte when I remember correctly) is needed
    when a cogc program is directly executed in cog ram by using cognew?

    Thanks,
    Christian
  • jazzedjazzed Posts: 11,803
    edited 2014-04-10 19:41
    But the part with the stack size still puzzles me. Are you sure that such a big stack size (EXTRA_STACK_LONGS is > 1kbyte when I remember correctly) is needed when a cogc program is directly executed in cog ram by using cognew?

    Oops.

    No it is not necessary for cogc. Sorry about the confusion.
Sign In or Register to comment.