Assembly, shared memory, multiple Cogs
Wurlitzer
Posts: 237
Sorry, I'm thick today (well maybe more than today). I have an application which will require 5 or more cogs (some with SPIN others in Assy) to read and write to a common Byte Array[noparse][[/noparse]100] in Main RAM.
I cannot get my head around how to assure all cogs know the starting address address of this common array. Does it require the array to be declared in the Top Object then have the Top Object call all the subseqent "CogNew(@SpinOrAssyObjectName,@@ByteArray[noparse][[/noparse]0])" and then the PAR register in each cog will contain the proper starting address?
I don't have any worries in this program regarding conflicting writes I just need to be able to read/write to any element in this 100 element ByteArray from any cog.
Thanks
I cannot get my head around how to assure all cogs know the starting address address of this common array. Does it require the array to be declared in the Top Object then have the Top Object call all the subseqent "CogNew(@SpinOrAssyObjectName,@@ByteArray[noparse][[/noparse]0])" and then the PAR register in each cog will contain the proper starting address?
I don't have any worries in this program regarding conflicting writes I just need to be able to read/write to any element in this 100 element ByteArray from any cog.
Thanks
Comments
1) In your routine to start these cogs, assign the address of this array to a long word in the assembly code for the cog like:
2) In your start routine, pass the address of the array as the parameter for the PAR register:
To read other bytes from the array, move the address to a temporary location and add the index to the temporary, then use rdbyte to read from the resulting address. To write to a byte, use wrbyte instead. Be careful in that a cog could read a byte, do some computation on it and write it back while some other cog wrote a value to the same byte between the first cog's read and write.
Again, thanks for the very quick reply.
Obviously, the propeller (minus the MIDI communication) can handle the processes above without a problem using SPIN. The oddball MIDI baud rate (~~32Kbaud) requires the higher speed provided by assembly and the communication baud rate to the pipe chamber will be much higher.
Where the Propeller chip (in assembly) shines in this application is when a Combination Action·button is pressed. It is possible the state of 200+ stop tabs will change simultaneously·and I have to determine what MIDI messages need to be sent to Record that change while at the same time not slowing down the data stream for the playing notes. I have come up with a method to reduce the data sent during this event in record or received in playback by 95% but it requires some very quick processing prior to sending the MIDI message.
I will also be recording/playback in MIDI via an SD card for those times I do not want to take the time to boot up my PC.
There are other systems on the market that fall short in performance, IMO, for this application. Some you can hear the playing notes slow down when a Combination Action button is pressed. They also are very complicated with hundreds of ICs. And, lets face, it some of this is simply a great way to learn Propeller programming.
It is people like you Mike (and others) that make this possible because of your willingness to share your expertise. Thanks.
I haven't read any of the other responses, but wanted to make a quick suggestion. You'd have no problem if you can coordinate your programming so each variable in the array is only read and written to once. Never have more than one application write or read to each variable. Follow this rule and you'll be fine.
-Parsko
Part of the 100 byte array is a circular queue and only the console (keyboard, pedal, stop tabs) routine writes to the circular queue.·Two other COGs routines simply read this queue and send any derived MIDI messages to a transmit queue (1 per COG). One of these 2·COGs sees both transmit queues and has the task of sending the data to the serial out routine/COG. As long as my serial out routine is functioning the 2 transmit queues will be serviced faster than they can fill. If my serial routine fails, the organ still plays but does not record and at that point the last thing I would be worried about is the transmit queues.
Thank you for your interest and comments.
Does the code below making any senses? I want to array to cog 2 when cog 1 stop
t:=0
repeat I From 0 To 180
Array1:=t
Debug.str(string(13,"counter="))
Debug.dec(t)
Debug.str(string(13,"Sin(t)="))
'C:=((b/2)*(t/200))
'd:=fMath.FSqr(C)
A:=fMath.Sin(fMath.Radians(fMath.FFloat(t)))
debug.str(fstring.FloatToString(A))
Array2[J]:=A
t:=t+1
waitcnt(clkfreq+cnt)
'ReceiveArray (@Array1,@Array2)
cogstop(0)
PUB Start2(I,J):Success
Stop
success:=( cog :=cognew(ReceiveArray(@long[Array1][5],@long[Array2][20]), @Stack1)+1)
PUB Stop
If cog
cogstop(cog~-1)
PUB ReceiveArray(temp1, temp2)
debug.start(31, 30, 0, 38400)
debug.tx(13)
waitcnt(clkfreq+cnt)
temp2:=Array2[5]
debug.str(string(13,"x="))
'debug.dec(temp2)
debug.str(fString.FloatToString(temp2))