Muliple starts (again)
kenmac
Posts: 96
After the confusion caused by incorrect Pin numbers in my previous thread, I am starting this one again.
The code that follows is a simple example of a problem that I have run into.
There are three Spin files, number_led, checkno, and led.
number_led starts the other two, as well as generating a variable called "number", and turns on LED20.
checkno starts its own Cog, and checks the number that is generated by number_led, and turns on LED16 if it = 5.
led starts its own Cog and simply flashes LED17 continuously.
number_led
checkno
led
If the code is run as shown, only LED17 flashes - LED20 isn't on, so the local start hasn't happened.
However, if I remove the "y.start", it works - LED20 is on, and LED flashes when the number = 5.
It seems that starting the second Object (y.start) prevents the following local start command from activating.
Removing the first start (x.start) doesn't fix it.
Can anyone please explain what is actually happening here?
In the previous thread I tested 4 Objects/Cogs OK, but they were all simply turning on LED's.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
The code that follows is a simple example of a problem that I have run into.
There are three Spin files, number_led, checkno, and led.
number_led starts the other two, as well as generating a variable called "number", and turns on LED20.
checkno starts its own Cog, and checks the number that is generated by number_led, and turns on LED16 if it = 5.
led starts its own Cog and simply flashes LED17 continuously.
number_led
var word numptr byte number obj x:"checkno" y:"led" pub main numptr := @number ' get address of GV x.start(numptr) ' start "test_checkno.spin" y.start ' start "test_led" start ' start local work pub start dira[noparse][[/noparse]20]~~ outa[noparse][[/noparse]20]~~ ' LED indicates path used number~ ' number = 0 repeat number++ ' increment number if number == 9 number~ ' start again waitcnt(8000_000 + cnt)
checkno
var long stack2[noparse][[/noparse]20] word NumPtr byte num pub start(MyNumPtr) NumPtr := MyNumPtr cognew(checkno, @Stack2) ' start new Cog to run checkno pri checkno repeat num := byte[noparse][[/noparse]NumPtr] ' get value in GV "number" if num == 5 ' trap number dira[noparse][[/noparse]16]~~ outa[noparse][[/noparse]16]~~ ' turn on LED else outa[noparse][[/noparse]16]~ ' turn off LED waitcnt(2000_000 + cnt)
led
var word stack0[noparse][[/noparse]50] pub main cognew(start, @stack0) ' start new cog pub start dira[noparse][[/noparse]17]~~ repeat !outa[noparse][[/noparse]17] ' toggle LED waitcnt(6_000_000 + cnt)
If the code is run as shown, only LED17 flashes - LED20 isn't on, so the local start hasn't happened.
However, if I remove the "y.start", it works - LED20 is on, and LED flashes when the number = 5.
It seems that starting the second Object (y.start) prevents the following local start command from activating.
Removing the first start (x.start) doesn't fix it.
Can anyone please explain what is actually happening here?
In the previous thread I tested 4 Objects/Cogs OK, but they were all simply turning on LED's.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
Comments
in the file led the method main starts a new cog but you are calling start. This method does not end while it contains an endless loop. So the method start in file number_led will be not executed.
Thomas
Cogs should be able to run independantly without affecting the one that called it.
In fact I have run 4 Cogs simultaneously that didn't terminate, and didn't affect the caller Cog - it works as expected.(earlier thread)
I want to find out why this particular code doesn't behave that way.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
Kaio is correct. You're not starting a new cog when you call the start method in led. You need to change the names in your led object.
But I find your code very - let's say - "complex": Why are you using all these different objects rather than start the COGs from one signgle main routine?
Other observations:
- You should not use WORD for stack-memory
- many of your "copies" are not really needed.
Stacks and objects have nothing to do with each other. You need a stack area for each cog that's executing a Spin program. The outermost method called by COGNEW/COGINIT must be in the same object as the COGNEW/COGINIT statement and it's easiest for the stack to also be in the same object, but you could start 3 cogs all in a program without any sub-objects like:
Thanks for that.
It was an incorrect start call - it should have been "y.main", not "y.start" .
I don't know how I missed that - just shows "fresh eyes" is best to spot errors.
DeSilva,
I am strictly at hobby level on this stuff, trying to build some confidence in what I'm doing! (with some help from the professionals)
Being new to the Prop systems, I have been "proving" methods before committing them to a project - the Manual/Tutorial doesn't tell you everything!
So, just simple examples are used, not necessarily practical, just to confirm the method works.
Why use multiple Cogs?
Well, I intend using the Prop. as a RTC, c/w battery backup - this will require shedding any power load caused by various independant functions generated from the Prop.
I want to have only 1 Cog operating(RTC) after a main power outage, to minimise the load on the battery, so the other functions would be in other Cog/s, which would be shutdown when on battery.
I am taking advantage of the Prop's parallel ability plus the low current drain.
Normally I would just use a PIC/s.
Thanks for your input.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
Nevertheless, it is quite tricky to save power. The best way of all ist to reduce the processor clock (PPL1X will have more effect than anything else). Then you can also extend the WAITCNT periods in critical situations; that is probably as efficient as shutting a COG down..
Re the Cogs v Objects
It seemed to me to be cleaner to run specific purpose Objects in their own Cogs, rather than run Cogs to handle different Methods listed in the first Cog.
It's probably the harder way to go.
Re power saving.
I was just working from the statement that the load was about 500uA for just 1 Cog operating at 5mHz.
The information inferred that the minimum load is obtained by running at lowest speed and restricting the number of Cogs running.
I think that the important area re the other Cogs is the output load on any pins that is created by them.
So, it seems the best to shutdown anything that creates a load on any pins - it's easy/cleaner to shutdown Cogs, then re-start them when main power resumes.
Once a minimum load is decided, the required battery capacity can then be determined.
I have working code for all the Cogs, I just need to confirm the inter-Cog data transfer actions before I put it all together.
Some of the problems have been self inflicted by straightout errors or by me not spotting "the obvious".
Sometimes we concentrate too hard on the code and develop "tunnel vision" !
With the help of the Forum it's all progressing, albeit in small steps.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
(1) You are right, when runnung @ 5 MHz (=PLL1X) current from and into I/O pins wil probably be the main contribution but that can be easily cut by floating the pins, which however can have drawbacks of other kinds... You might be right, using "brute force"
However consult the nice power dissipation diagram on one of the last pages of the datasheet. It gives you additional insight in the order of magnitudes involved. Power dissipation generally increases with the square of clock rate....
(2) I still have the funny presumption there is some confusion wrt to objects and COGs. Can you attest me that a process in a COG has nothing whatever to do with the concept of modularization by objects? I should be relieved..
You can write a multicog, complex program in assembly language, all in one source file, that's assembled by Cliff Biffle's (or anyone else's) assembler that has nothing to do with Spin and doesn't support it. You can also write a similar program (assuming that the speed of Spin allows it) in Spin using multiple objects or a single object. Objects, as supported by Spin, naturally support the multi-cog nature of the Propeller, but are not necessary, merely convenient at times.
Mike