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?
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.
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?
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.