Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

code execution sequence


crs Apr 17, 2018 10:48 PM

I am trying to understand how CRBasic decides which order to execute different code blocks within my program, and create the following as an example.  (I am using the _Debug() code that was posted elsewhere on this forum)

ShutdownBegin
    Call _Debug ("Entering ShutdownBegin code block")
ShutdownEnd

BeginProg
    Call _Debug ("Start of BeginProg code block")

    Scan (1,Sec,1,0)
        Call _Debug ("Start of Scan code block") 
    NextScan

    SlowSequence
        Call _Debug ("Start of SlowSequence code block")
        Do
            Call _Debug ("Start of Do/Loop code block")
        Loop
    EndSequence
EndProg

The program complies in pipeline mode, and surprisingly (to me), the output in my debug file is in the following order: 

SlowSequence
Do/Loop
... (multiple iterations)
BeginProg
Do/Loop
...
Scan
Do/Loop
...
Scan
Do/Loop
...
Scan
Scan
Do/Loop
...
Shutdown

I was expecting that the code immediately following BeginProg would execute first, followed by code at the top of the Scan loop, then the SlowSequence and multiple Do/Loops.  How does CRBasic decide on the order of these various cod sections?


JDavis Apr 17, 2018 11:17 PM

Your scan has a 1 second interval, so it would not begin to execute until the top of the next second. It is a fraction of a second delay.


crs Apr 18, 2018 12:34 AM

Understood -- the Scan loop triggers based on the data logger clock.  But why does the SlowSequence execute before the instructions immediately after BeginProg but before the Scan loop?


DAM Apr 18, 2018 02:08 PM

You must consider all sequences (i.e. the "main" sequence and slow sequences) as independent "tasks" or threads. All of these tasks start after the program is compiled and vie for processor time to execute their part of the program. Only when the sequences require a shared resource (such as measurement or a communications port,...etc) is there arbitration between them. The program can force arbitration by using a global variable, or much safer, the SemaphoreGet/SemaphoreRelease instructions. This is only required if you need to protect a resource (variable or piece of code etc.) that is used in more than one sequence, or if you must guarantee that one section of code runs before another.

The key concept to understand is that each sequence behaves as its own program and runs at the same priority as other sequences, when there is a conflict internally, the main sequence has first priority, then the first slow sequence,, and so on. A conflict is defined as two or more tasks trying to use the same resource at the same time.

In your case, as soon as the main sequence encouters the scan instruction, it will wait to sync the scan interval to real time. At this point, the slow sequence has "free rein" of the processor and can run its portion of the program.

Log in or register to post/reply in the forum.