confused about sharing data between cogs when using XMMC and cog memory models
sssidney
Posts: 64
I'm confused about sharing data between cogs when using XMMC and cog memory models. In this example
I've declared 3 globals in the main routine compiled in XMMC mode and tried to write to them in a cog mode routine.
The writes never seem to happen when the main is compiled in XMMC mode. When I compile with the main routine in LMM mode it works fine.
I've compiled the code with the optimizer turned off. I'm obviously missing something pretty basic.
Here is the main routine/file:
Here is the cogc code:
Output from XMMC mode:
starting main in cog 3
before - sharedInt1 0 sharedInt2 0 sharedInt3 0
cogstart 0
after - sharedInt1 0 sharedInt2 0 sharedInt3 0
Output from LMM mode:
starting main in cog 0
before - sharedInt1 0 sharedInt2 0 sharedInt3 0
cogstart 1
after - sharedInt1 123 sharedInt2 456 sharedInt3 789
Any help is greatly appreciated.
Thanks!!!
I've declared 3 globals in the main routine compiled in XMMC mode and tried to write to them in a cog mode routine.
The writes never seem to happen when the main is compiled in XMMC mode. When I compile with the main routine in LMM mode it works fine.
I've compiled the code with the optimizer turned off. I'm obviously missing something pretty basic.
Here is the main routine/file:
#include <stdio.h> #include <propeller.h> #define STACK_SIZE 32 struct { unsigned stack[STACK_SIZE]; int m; } parms; extern _Driver _SimpleSerialDriver; _Driver *_driverlist[] = { &_SimpleSerialDriver, NULL }; int sharedInt3 = 0; volatile int sharedInt2 = 0; HUBDATA volatile int sharedInt1 = 0; int startWav(void *parptr) { extern unsigned int _load_start_tst1cogc_cog[]; return cognew(_load_start_tst1cogc_cog, parptr); } int audioCogId = -1; int main (int argc, char* argv[]) { waitcnt(CNT + CLKFREQ); printf("starting main in cog %d\n", cogid()); printf("before - sharedInt1 %d sharedInt2 %d sharedInt3 %d \n", sharedInt1, sharedInt2, sharedInt3); audioCogId = startWav(&parms.m); printf("cogstart %d\n", audioCogId); waitcnt(CNT + (CLKFREQ*2)); printf("after - sharedInt1 %d sharedInt2 %d sharedInt3 %d \n", sharedInt1, sharedInt2, sharedInt3); return 0; }
Here is the cogc code:
#include <propeller.h> extern int sharedInt3; extern volatile int sharedInt2; HUBDATA extern volatile int sharedInt1; _NATIVE void main (volatile int *m) { sharedInt1 = 123; sharedInt2 = 456; sharedInt3 = 789; }
Output from XMMC mode:
starting main in cog 3
before - sharedInt1 0 sharedInt2 0 sharedInt3 0
cogstart 0
after - sharedInt1 0 sharedInt2 0 sharedInt3 0
Output from LMM mode:
starting main in cog 0
before - sharedInt1 0 sharedInt2 0 sharedInt3 0
cogstart 1
after - sharedInt1 123 sharedInt2 456 sharedInt3 789
Any help is greatly appreciated.
Thanks!!!
Comments
See the toggle/cog_c_toggle demo for an example.
COGs should always share data via mailbox pointers.
Spin has a problem with global variables like in the example. Spin methods can access any data in VAR or DAT directly, but cog code has to get the variable addresses or add an offset for things to work when accessing global data. LMM works both ways because it is in the global map.
Propeller-GCC cognew does work properly with xmm modes when the mailbox rule is followed. I use it all the time with xmmc. If you want to use xmm-single or xmm-split, you have to copy the cog memory from the xmm space to HUB space before doing cognew. XMMC or LMM doesn't require copying because all data lives in HUB RAM. The failure here is lack of documentation.
For any XMM memory model where a COG-C program is used, we need to copy code to HUB memory for cognew to work; COG-C programs live in the text segment. The demos/toggle/cog_c_toggle program does not copy the code first, and will fail in XMMC mode. Any imported PASM program like used in demos/toggle/pasm_toggle will work fine in XMMC mode without copying first (but not XMM-SINGLE or XMM-SPLIT).
My earlier post omits the step of copying the COG from XMMC code space to HUB memory. Sorry about that.
To make the demos/toggle/cog_c_toggle program work, two things need to be changed (this needs to be fixed before our next distribution):
1) The pins toggled should not include the XMMC storage pins. Remove the 3 from the pins declaration for EEPROM XMMC. Other XMM solutions may need other adjustments.
2) The start function should be replaced with something like this:
You're thinking of binary blobs (PASM compiled to .DAT). In fact COGC code can share data directly -- the linker will fix up data references. That's why we have to go through some hoops to link COGC programs.
The problem is that the COGs aren't even running, because cognew does not work on text (such as the COGC code) in XMM or XMMC modes. It does work on binary blobs, because (as you say) they're stored in hub memory. COGC code is not.
The cog_c_toggle code actually does work in XMM mode, it has #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__) in the places where LMM and XMM differ.
Eric
Thanks.