View Single Post
  #28  
Old 10-14-2011, 01:03 PM
jpearman's Avatar
jpearman jpearman is offline
Senior Member
VEX # 8888
 
Join Date: Apr 2011
Location: Los Angeles
Posts: 2,804
Re: RobotC programming tips

Iím going to discuss multi-tasking a bit more and the task scheduler. As there is little documentation on this aspect of RobotC most of this discussion is a best guess and may be incorrect in some of the fine details.

Consider a group of students sitting around a table having a discussion with their teacher. If a student wants to speak then they have to raise their hand and wait for the teacher to give them permission. If several students have their hands raised the teacher will choose each one in turn so everyone can be heard. Some students may want to speak often and keep raising their hands, others may be sleepy and not participate much at all. The teacher is also watching a clock, if a student speaks for too long then the teacher will interrupt them and give someone else a turn. At one point the school principle joins the debate, he also has to raise his hand to be able to speak but, as he is considered more important, the teacher always gives him priority.

This analogy describes quite well how the RobotC task scheduler works. The task scheduler (the teacher in my example) determines which task (student) can run. The principle represents a high priority task that has precedence over the others. When several tasks of the same priority want to run the scheduler chooses them in turn. If a task continues running too long then the scheduler stops it and gives time to others.

To show how this works in practice Iím going to use a modified version of the code presented a couple of posts back that flashes two LEDs. Iíve modified the code a little so that everything happens much faster and we can observe the signal going to the LEDs on an oscilloscope. An oscilloscope lets us look at the level of a signal (itís voltage) over time and creates a graphical representation. More background on oscilloscopes is here http://en.wikipedia.org/wiki/Oscilloscope.

Hereís the test code we will use, very similar to before but the while loops only wait for 1mS and 2mS respectively.

Code:
#pragma config(Sensor, dgtl1,  LED_1,               sensorDigitalOut)
#pragma config(Sensor, dgtl4,  LED_2,               sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

// Flash the first LED
task flashLed_1()
{
    while( true )
        {
        // toggle output
        SensorValue[ LED_1 ] = 1 - SensorValue[ LED_1 ];

        wait1Msec( 1 );
        }
}

// Main task - flash the second LED
task main()
{
    // Start the other task
    StartTask( flashLed_1, 6 );

    // Do our own thing
    while( true )
        {
        // toggle output
        SensorValue[ LED_2 ] = 1 - SensorValue[ LED_2 ];
        
        wait1Msec( 2 );
        }
}
If we observe the digital outputs on the scope we see the following, the value of LED_1 is shown by the yellow trace, LED_2 the blue. LED_1 is changing state every 1mS, LED_2 is changing state every 2mS. This corresponds exactly to the wait1Msec delays we have in the two tasks, each task does itís thing and then sleeps until woken again by the task scheduler.



For the next example we replace the wait1Msec(1) statement in the flashLed_1 task with a different command, AbortTimeSlice. This command hands control back to the task scheduler which then decides if any other tasks are waiting to execute (have their hands up), if none are waiting then control is given back to flashLed_1, lets see this on the scope.

Code:
// Flash the first LED
task flashLed_1()
{
    while( true )
        {
        // toggle output
        SensorValue[ LED_1 ] = 1 - SensorValue[ LED_1 ];

        AbortTimeSlice();
        }
}


You can observe that LED_1 is now flashing very fast as the only other task we have created is the main task which sleeps for 2mS before wanting to run. Both tasks still operate but the majority of the time is spent running the flashLed_1 task. If you are wondering what the large gap in the yellow trace is, well in the previous post I explained that RobotC already has other tasks running for debugging purposes, this gap occurred when the RobotC task, presumably a more important task, needed to run.

To be continuedÖÖ.
Attached Images
File Type: jpg TEK00006.jpg (12.1 KB, 2859 views)
File Type: jpg TEK00007.jpg (12.9 KB, 2860 views)
Reply With Quote