Here is a simple example that uses two tasks. The first task shows "Hello" and "nurse" on the display. The second task just waits for the Run button to be pressed. When it is pressed, the first task
is stopped, the second task ends, and control returns to legOS.
#include "conio.h"
#include "direct-button.h"
#include "unistd.h"
#include "sys/tm.h"
pid-t pid;
int display_task(int argc, char ∗∗argv) {
while(1) {
cputs("Hello");
lcd_refresh();
sleep(1);
cputs("nurse");
lcd_refresh();
sleep(1);
}
return 0;
}
int stop_task(int argc, char ∗∗argv) {
msleep(200);
while (!PRESSED (button_state(), BUTTON_RUN))
;
kill(pid);
return 0;
}
int main() {
pid = execi(&display_task, 0, NULL, 0, DEFAULT_STACK_SIZE);
execi(&stop_task, 0, NULL, 0, DEFAULT_STACK_SIZE);
Page 201
tm_start();
return 0;
}
Let's start at the bottom and work our way up. The main() method uses execi() to start the two tasks: display_task() and stop_task(). The process ID of the display task is saved
away in the pid variable so that it can be stopped later. The last thing main() does is call tm_start() to start the task manager, which actually handles running the tasks.
The stop_task() waits for the Run button to be pressed. When the button is pressed, stop_task() calls kill() to stop the display process. What's that call to msleep() at the
beginning of stop_task()? When legOS first boots on the RCX, it's waiting for the Run button to be pressed. As soon as it is, your program is started. It's very possible that stop_task()
will already be running before you have a chance to take your finger off the Run button. The call to msleep() simply delays a little while to give you a chance to release the Run button.
The display_task() is straightforward. It alternates between displaying "Hello" and "nurse" on the display, looping forever until it is killed by stop_task().
Waiting (unistd.h)
For a cleaner way to wait for specific events, consider wait_event():