Upload
bordis
View
269
Download
0
Embed Size (px)
Citation preview
Introduction to Lab 2Programming in RTOS using LEGO Mindstorms
Martin Stigge <[email protected]>
9. November 2009
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 1 / 20
Lab 2: Programming in RTOS using LEGO Mindstorms
Lab goals:I Basic programming on an embedded deviceI Using the API of an RTOS for current tasks
Lab preparation:I Form groups: 3 students eachI Possibly refresh your C knowledgeI Make sure your Windows login works!I Lab will be done on Fri, 13.11. and 20.11. in rooms 1312D and 1313DI Have a look at the lab homepage
http://www.it.uu.se/edu/course/homepage/realtid/ht09/lab2
Lab report:I C code to all 5 partsI Answers to the questionsI To my mailbox, building 1, floor 4; Deadline: Mon, 14.12. at 10:00
Further:I Demonstrate a working vehicle, participate in car race on 11.12.I Return all hardware you get
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 2 / 20
LEGO Mindstorms
Programmable LEGO brick with sensors and motors
Comes in two generations:
RCX generation (1998) NXT generation (2006)
We will use the RCX platform
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 3 / 20
LEGO Mindstorms: Components
Package contents:
RCX unit:I LCD display, 5 digitsI 4 ButtonsI Sensor inputs 1, 2, 3I Motor outputs A, B, CI Infrared (IR) portI Can store 8 programs
Two touch sensors
One light sensor
Two motors
RCX Internals:
Hitatchi H8/3292, 32k RAM, 16k ROM, 8/16-bit architecture, 16MHz clock
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 4 / 20
RTOS: LegOS (BrickOS)
We don’t use the standard firmware
Instead: LegOS (nowadays “BrickOS”)I (Soft) Real-time operating systemI Multitasking OS coreI Provides C/C++ development environmentI Support for threads, priorities, semaphores, event handlingI Comprehensive API for low-level I/O accesses
Rest of this introduction: How toI Upload the firmwareI Compile/upload programsI Write programs/use LegOS API
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 5 / 20
LegOS: Firmware Upload
1 Start Cygwin (see lab homepage)
2 Compile firmware uploader if necessary (see lab homepage)3 Upload firmware:
(i) Power up RCX unit (six AA batteries, “On/Off” button)(ii) Power up IR transceiver (one 9V block battery)(iii) Connect IR transceiver to COM port(iv) Run firmdl:
Example Run: Firmware upload
$ cd /legos
$ util/firmdl -s boot/legos.srec
Transferring "boot/legos.srec" to RCX ...
100%
$
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 6 / 20
LegOS: Program Compile/Upload
1 Compile program using make2 Upload program using util/dll
I RCX and IR transceiver need to be running (and idle)
Example Run: Program compile/upload
$ cd /legos/demo
$ make
...
$ cd ..
$ util/dll demo/helloworld.lx
$
To compile own programs:
Edit demo/Makefile and add newprogram.lx to PROGRAMS= row
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 7 / 20
Remark: Working At Home
You can do all this at home (using Windows/Linux/Mac)
Some hints at lab homepage
Biggest issue: IR transceiver needs COM port (RS-232)
RS-232 port
Only few boxes with USB
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 8 / 20
Programming For LegOS
“Ordinary” C programs
Have a look at demo/ directory!
Listing: helloworld.c
1 #include <conio.h> // cputs(), cls()
2 #include <unistd.h> // sleep()
3
4 int main(int argc , char **argv) {
5
6 cputs("hello");
7 sleep (1);
8 cputs("world");
9 sleep (1);
10 cls();
11
12 return 0;
13 }
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 9 / 20
Programming For LegOS
“Ordinary” C programs
Have a look at demo/ directory!
Listing: helloworld.c
1 #include <conio.h> // cputs(), cls()
2 #include <unistd.h> // sleep()
3
4 int main(int argc , char **argv) {
5
6 cputs("hello");
7 sleep (1);
8 cputs("world");
9 sleep (1);
10 cls();
11
12 return 0;
13 }
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 9 / 20
LegOS API
LegOS C programs can’t use standard C library
But API offers a lot, includingI Input/Output (on LCD)I Reading sensors (light/touch)I Controlling motorsI Time functions (delay)I Random numbersI Multithreading (forking, semaphores)I Wakeup on events
Will do a short walk-through now
See “LEGO Command Reference”!
(Include corresponding header files!)
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 10 / 20
LegOS API: I/O
Input via buttons
Input via sensors (see next slide)
Output via LCD: Strings, integers and sound
Example: User Input/Output
1 // Input via buttons
2 if (getchar () == KEY_VIEW) { // Blocking call!
3 ...
4 }
5
6 // Output
7 cls(); // Clears LCD
8 cputs("Foo"); // String Output
9 lcd_int (42); // Integer Output
10
11 dsound_system(DSOUND_BEEP); // Short "beep"
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 11 / 20
LegOS API: Sensors
Touch/light sensors on inputs 1, 2 and 3
Read values from boolean/integer variablesI TOUCH 1, TOUCH 2, TOUCH 3: Touch sensors (boolean)I LIGHT 1, LIGHT 2, LIGHT 3: Light sensors (integer)
Active/passive mode
Example: Sensor input
1 #define DARK_THRESHOLD 42
2 ...
3
4 ds_active (& SENSOR_1); // Set 1st sensor to active mode
5 ...
6 if (LIGHT_1 < DARK_THRESHOLD) {
7 // Handle darkness
8 }
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 12 / 20
LegOS API: Motors
Motors can go forward/backward
.. at a certain speed (between MIN SPEED and MAX SPEED)
Can also brake (block movements)
Example: Motor Control
1 // Motor A full speed forward
2 motor_a_dir(fwd);
3 motor_a_speed(MAX_SPEED);
4
5 // Everything full stop
6 motor_a_dir(brake);
7 motor_b_dir(brake);
8 motor_c_dir(brake);
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 13 / 20
LegOS API: Time and Randomness
Delay execution: sleep() (seconds) and msleep() (milliseconds)
Busy waiting: delay()
Generate random number: random() and srandom() (set seed)
Example: Time and randomness
1 sleep (23); // Sleep for 23 seconds
2
3 long int x = sys_time; // Read current time in ms
4 x += 1234; // Set x to time point 1234ms later
5 ...
6 sleep(x - sys_time); // Wait until time point x
7
8 srandom(sys_time); // Initialize random seed with systime
9 if (random () % 42 == 23) {
10 ... // Execute this with (not too) low probability
11 }
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 14 / 20
LegOS API: Creating Threads
Create new thread from a function: execi()
pid_t execi(&PROCESS_FUNC, int argc, char *argv[],priority_t priority, size_t stack_size);
PROCESS FUNC is function for new threadI Two arguments: int and char**I Returns an int
Pass arguments via global variables or argc/argv
Priorities: Between PRIO LOWEST (1) and PRIO HIGHEST (20)
Example: Creating Threads
1 // Define thread function
2 int foo(int argc , char *argv []) { ... }
3 ...
4 // Create thread (starts running immediately !)
5 execi(foo , 0, NULL , PRIO_NORMAL , DEFAULT_STACK_SIZE);
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 15 / 20
LegOS API: Events
Suspend thread until wake-up event: wait event()wakeup_t wait_event(wakeup_t(*wakeup) (wakeup_t),
wakeup_t data);wakeup is function for event check
I Argument and return type: wakeup t (i.e., integer)I Is called by OS every 20ms, releases thread if non-zero return value
Example: Event Waiting
1 // Define wake -up function
2 wakeup_t sensor_press_wakeup(wakeup_t data) {
3 return TOUCH_1 || TOUCH_3;
4 }
5 ...
6 // Wait for event
7 wait_event(sensor_press_wakeup , NULL);
8 // Sensor pressed!
Note: sleep() is implemented like this. (Exercise: How?)
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 16 / 20
LegOS API: Semaphores
Used for signalling between threads, e.g., lockingI Type: sem tI Init: sem init(sem t *sem, int pshared, unsigned int value)I Blocking Wait: sem wait(sem t *sem)I Non-blocking Wait: sem trywait(sem t *sem)I Release: sem post(sem t *sem)
See also: API reference
Example: Locking Using A Semaphore
1 int A;
2 sem_t Asem;
3 sem_init (&Asem , 0, 1); // Semaphore gets initial value 1
4 ...
5 sem_wait (&Asem); // Aquire lock for A
6 A = 42; // Change A
7 sem_post (&Asem); // Release lock for A
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 17 / 20
Lab Assignment
Part 1: Simple Light DetectorI Attach only light sensorI Write simple “Geiger counter”: More Light = Faster BeepingI Nothing fancy, just to get a soft start
Part 2: Static Cyclic SchedulingI Build a car from LEGO bricks, with motors and collision detectorsI Write four tasks to control it and a cyclic scheduler for them
Part 3: Adding a watchdog taskI Add a watchdog task to Part 2
Part 4: Multitasking in BrickOSI Restructure program to use multiple threads (one for each task)I Add light sensor and line tracking
Part 5: LEGO Car RaceI Tune car so that it can follow a track as fast as possible
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 18 / 20
LEGO Car Race
Track looks roughly like this:
Competition takes place on Fri, 11.12.I Fastest team wins! (Prize award included)I Timeout is 5 minutes (if more: assignment failed, fix car)
Keep in mind: Demo conditions might differ (different light etc.)
Some hints:I Build a physically robust car
F It should not break by itself!I No hard-coding of light thresholds
F Calibrate at program start!
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 19 / 20
The End
Questions?
(Now: Get LEGO boxes in groups of 3.)
Martin Stigge <[email protected]> Lab 2: LEGO 9. November 2009 20 / 20