Shop OBEX P1 Docs P2 Docs Learn Events
Muliple starts (again) — Parallax Forums

Muliple starts (again)

kenmackenmac Posts: 96
edited 2007-08-10 20:11 in Propeller 1
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
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

  • KaioKaio Posts: 253
    edited 2007-08-08 09:38
    kenmac,

    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
  • kenmackenmac Posts: 96
    edited 2007-08-08 13:55
    Kaio,
    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
  • Mike GreenMike Green Posts: 23,101
    edited 2007-08-08 14:04
    kenmac,
    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.
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-08 15:45
    A very annoying mistake smile.gif

    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.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-08-08 16:09
    Fred,
    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:
    VAR long stack1[noparse][[/noparse]30], stack2[noparse][[/noparse]30], stack3[noparse][[/noparse]30]
    
    PUB main
       cognew(newCog(1),@stack1)
       cognew(newCog(2),@stack2)
       cognew(newCog(3),@stack3)
       repeat
       ' do stuff
    
    PRI newCog(cogNumber)
    ' do stuff
    
    
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-08 19:47
    Mike, if I had your patience, I would be an angel.... smile.gif
  • kenmackenmac Posts: 96
    edited 2007-08-09 00:40
    Mike,
    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
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-09 17:25
    Kenmac, I wondered why you used different objects, not different COGs, as I have the shrewd presumption there is still some confusion....

    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..
  • kenmackenmac Posts: 96
    edited 2007-08-10 02:00
    DeSilva,
    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
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-10 04:09
    Kenmak,
    (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" smile.gif

    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.. smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-08-10 05:17
    deSilva,
    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
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-10 20:11
    Mike, this is a misunderstanding: I was playing devil's advocate - but thank you, nevertheless smile.gif
Sign In or Register to comment.