Lab Dates:
Report and Demo Due Dates:
Objectives:
Equipment, Parts, and Provided Software:
Documentation:
Background:
68332-based microcomputer: All of the laboratory exercises will use the New Micros NMIX-0332-OEM 68332-based microcomputer. This system is a typical 32-bit single-board computer for embedded control applications. The Motorola 68332 microcontroller chip is a relatively old part, but its architecture and interface subsystems are still representative of more recent 32-bit controllers. The 68332 contains a CPU32 microprocessor (upwardly compatible in user mode with the original 68000), a time processing unit (TPU), a queued serial module (QSM), a system integration module (SIM), a 2048-byte random-access memory (RAM) with separate battery power pin, a connection to an external system bus, and various software-reconfigurable inputs and outputs. The CMPE 401 microcomputer is almost identical to the one that is used in EE 380, but the amount of random-access memory has been increased from 128 kbytes to 256 kbytes. Also, some of the jumper connections are different and the silkscreened lettering on the printed circuit board (PCB) is slightly different. The memory map is identical for the two systems in every respect except that the user RAM in the CMPE 401 system extends from 0x03000 up to 0x03FFFF instead of up to only 0x01FFFF.
Kernels: In this laboratory you will be running a real-time multitasking kernel called MicroC/OS-II on the 68332-based microcomputer. A kernel is software infrastructure that provides basic services to user-written programs called tasks. The kernel takes care of the details of sharing the available CPU time among the ready-to-run tasks. A kernel also provides functions for creating, scheduling and terminating tasks. It also can provide semaphores to permit inter-task synchronization, and a message system for inter-task communication. A pre-emptive kernel is one that associates priorities with tasks, and then schedules higher priority ready-to-run tasks to execute on the CPU in preference over lower priority tasks. A real-time kernel is a kernel that has been designed to provide predictable execution time behavior and relatively fast real-time response to hardware interrupts. By using a kernel, a software designer can be much more productive by being able to leverage an existing infrastructure of (hopefully) well-written and thoroughly debugged software that provides much of the required application-independent functionality.
MicroC/OS-II: MicroC/OS-II, distributed by Micrium Inc., is a portable real-time kernel with strictly-prioritized preemptive scheduling. A maximum of 63 application tasks, organized in a fixed priority order (priority IDs 0 down to 62), can be active in the system at any one time. A special 64-th task, the idle task, executes on the CPU at the lowest priority (ID 63) when none of the application tasks is ready to run. As well as providing basic task management functions (create, delete, change priority, suspend/resume, etc.), MicroC/OS-II also provides semaphores, mutual exclusion semaphores, event flags, message mailboxes, and message queues. This kernel has been successfully ported to over 100 different microcomputer architectures, including the Intel IA-32 architecture (which includes the Pentium series microprocessors), the MIPS R4000, the ARM7, the Altera 32-bit NIOS, the Xilinx MicroBlaze, the IBM PowerPC 405, and the Microchip PIC-18xx. The kernel has been used in commercial products, and a validation suite is available to facilitate the certification of MicroC/OS-II-based systems in safety-critical applications. MicroC/OS-II software, written in ANSI C, is distributed royalty-free to educational institutions for teaching purposes; however, a licence is required from Micrium Inc. to include the kernel in commercial products. A TCP/IP stack is available for MicroC/OS-II, but this extension is not required in the first laboratory exercise. MicroC/OS-II is very convenient for our purposes in CMPE 401, and should be portable for use in other project-based courses.
Most of the software that you will be required to design will be written in C. Interrupt service routines must be written in CPU32 supervisor mode assembly language. Your programs can access the various library functions provided by MicroC/OS-II. You will use the provided makefile, with some modifications of your own, to compile and link together software loads for the microcomputer.
You will find that you will only need to use a small subset of the available MicroC/OS-II functions in your software designs. Some of the most useful functions are listed in the table below:
| Name | Purpose |
|---|---|
| OSInit | Initializes MicroC/OS-II kernel. Creates Idle task. Optionally creates Statistics task. |
| OSStart | Starts multitasking. Must have previously created at least one application task. |
| OSStatInit | Initializes Statistics task. Initialized by the start-up task before other tasks are created. |
| OSTaskCreate | Create a task with given C function, arguments, stack and priority. |
| OSTaskCreateExt | Extended version of OSTaskCreate with more input arguments. |
| OSTaskDel | Delete (remove from multitasking) a task that currently has no assigned resources. |
| OSTaskDelReq | Used by one task to tell another task to release its resources
and to delete itself. Also used by a task to determine if another task has asked it to delete itself. |
| OSTaskResume | Resume a suspended task. This routine can also be called to determine if a specific task has been suspended. |
| OSTaskSuspend | Suspend the specified task. |
| OSQCreate | Create a queue (circular buffer) for inter-task communication. |
| OSQPend | Receive the next message from a queue, else get blocked. |
| OSQPost | Send a message to a previously created queue. |
| OSSemCreate | Create a counting semaphore with a given initial count value. |
| OSSemPend | Block the calling task until given semaphore count exceeds zero. |
| OSSemPost | Signal (increment) the given semaphore. |
| OSTaskQuery | Request information on the specified task |
| OSTimeDly | Reschedule the calling task after a given time delay in clock ticks. |
| OSTimeDlyHMSM | Reschedule the calling task to a given time given in hrs, mins, secs and ms. |
Pre-lab Work:
Purchase the CMPE401 kit from the EEClub for $25. Only one kit is required per group.
All of the parts required for Lab 1, Lab 2, Lab 3, and Lab 4 are included in the kit.
If you already have the parts or you wish to purchase them elsewhere, feel free to
do so. Ultimately, you must have the parts listed on each lab handout to complete
the labs. The list of parts is provided above.
Sign out a breadboard and an extra DB9 cable from the lab instructor prior to your first lab session. For sections D1 and D3, the lab instructor will be in the lab on Friday, September 17th, between 2 and 5PM, and Monday, September 20th, between 2 and 5 PM to distribute the breadboards and cables. For students in D2 and D4 sign out your breadboard and DB9 cable at the times specified above or during the scheduled lab periods for D1 and D3 prior to your first session.
Wire up the breadboard according to the schematic diagram. The breadboard will be connected to the microcomputer over a ribbon cable that connects to a header that is plugged down into the breadboard. You will need to use pliers to carefully bend the pins of the header outward (two bends per pin) so that the header can be inserted down into the breadboard over across the middle slot. The ribbon cable and header connection will allow you to easily make connections on the breadboard to all wires in the ribbon cable (and thus connect to all of the required microcomputer signals). Place the flip-flop and LEDs according to the suggested floorplan. Be sure to keep the wires relatively short and tidy so that they will not get in the way and will not be easily dislodged. You will be re-using the circuits from this first laboratory exercise in the second and third labs, so it is wise to do a good wiring job in the first lab. The pre-lab work will be checked off by a TA shortly after the start of the lab period.
Be sure to bring a set of pliers and wirecutters with you to the lab session as these will not be provided to you.
Exercise #1: Compile, download and verify an initial system load.
tar xvf cmpe401.tar.
NEVER repeat this step in this or any other lab or you will overwrite
and lose all of your work!
(If you have to untar the main .tar file again, then be sure to save copies
of the files that you want to keep in a completely different directory in
your account.)
If the untar operation was successful then a particular directory structure
should have been created in your account.
This directory structure is documented here.
make.
This will compile the lab1.c application and link it with the lwip
and uC/OS rom images provided in the cmpe401/bin directories.
You should now have the files lab1.s19 and lab1.map
minicom
lo and press enter
to get the monitor ready to load in an .s19 file.
cat lab1.s19 >/dev/ttyS0
to transmit the .s19 file out through the COM1 serial port.
go 10000 in the minicom window to launch
the MicroC/OS-II system.
Exercise #2: Using tasks to control LEDs through a memory-mapped register and display statistics about uC/OS-II .
For this exercise you will be using tasks to control the state of eight LEDs
through a memory-mapped register connected to the external expansion bus
of the 68332.
You must modify the given source file lab1.c, which is provided to
you containing two dummy tasks called StatsDisplayTask()
and LEDToggleTask().
Your new code will be inserted into these two tasks only.
Do not modify the other code!
Your code will have to display data into the minicom terminal window on the
Linux host using the functions in the I/O library.
Read through cmpe401/lib/io.c to familiarize yourself
with the available I/O functions.
Specifically, you will be using outstr(),
and outchr()
to display strings and characters, and intstr() to convert
integers into the corresponding character strings.
Note: The standard C library stdio.h is not available in the
MicroC/OS-II environment so do not attempt to use functions such
as printf() or putc().
The kernel has been set up to produce two oscilloscope test signals using
the scope libraries found in cmpe401/lib/scope.s.
You should read and understand the functions in scope.s.
The kernel will toggle PCS0 on a clock tick and toggle PCS1 on a
context switch.
Therefore if a 32-Hz square wave is present on the PCS0 (Peripheral Chip
Select 0) pin of the 68332, then MicroC/OS-II is running.
PSC1 can be used to verify that tasks are being scheduled.
Using the scope() function you might, in future labs,
find it useful to send signals to the remaining PCS channels
for debugging purposes.
StatsDisplayTask() is to be
modified to obtain the current OS time in ticks using OSTimeGet()
and to convert the returned integer to a string using intstr().
The task should then obtain task information for all running tasks
using OSTaskQuery().
Again the returned integers will have to be converted to strings.
The task is then to display the information in a table in the terminal window.
The table should list each task's name, priority, status, stack bottom and
stack top. The status information should indicate all of the possible
status states. For example, ready, suspended, pending on a queue, etc.
An updated table is to be redisplayed every 5 seconds.
The screen should be cleared before displaying a new table by sending
the ASCII code 0x0C.
Your output should look something like this.
LEDToggleTask() is to be modified to periodically
flash the LEDs on (for 1 second) and off (for the balance of the time)
in a repeating pattern every 4 seconds.
The boot.s code will map the LED register's chip select to a 2-Kbyte block
at memory base 0xA00000.
Therefore any address from 0xA00000 to 0xA007FF will be mirrored to the
LED register. An LED command buffer utilizing MicroC/OS-II's message queue system
has been provided.
The task LEDDisplayTask() already exists in your code and does not
need to be modified.
This task blocks until at least one command is placed in the buffer.
To put a command in the buffer a task calls LEDBufferPost().
The first parameter of this function is the LED number (0-7) and the
second parameter is the LED state, either 0 (LED off) or 1 (LED on).
You may have to send eight commands in sequence to get all LEDs to be on or
off.
Save and make the modified code and download it to the 68332 target. Run the code and verify that both of your tasks are running properly. Also note any changes to the scope signal on channel 2 (pin PCS1). Be sure to record the system performance numbers that are being displayed so that you can include them in your report. Modify the value passed to OSTimeDly to determine the effect this has on system performance. Choose 2 other time values for StatsDisplayTask and LEDToggleTask and include the results in a table in the lab report. Demonstrate your working system to the lab instructor before proceding to the next exercise.
Exercise #3: Input from the keyboard and synchronization using semaphores.
In this exercise input from the keyboard will control the suspension and resumption of any of the 4 running tasks. SciInit initializes the vector table to ensure that input from the keyboard works correctly with uC/OS-II. The characters typed in at the keyboard generate interrupts that execute the associated interrupt service routines automatically. The interrupt service routine calls RxPost to place the character in RxBuffer and deposit the pointer to the character into the RxQueue. To retrieve the characters typed in, retrieve the pointer to the character from the RxQueue using the appropriate uC function.
The StatsDisplayTask should continue to display the statistics that you displayed in exercise 2. Some modifications to StatsDisplayTask will be required for synchronization with KeyReadTask as discussed below, otherwise the same stats displayed in exercise 2 should be displayed in exercise 3. LEDToggleTask and LEDDisplayTask do not require any modifications, and should be running.
Synchronization will be required between the StatsDisplayTask, and the KeyReadTask. If you do not insert the synchronization required, one task will overwrite the data printed to the screen by the other task. To accomplish this synchronization, two semaphores have been created for you to signal to StatsDisplayTask and KeyReadTask that their respective turns have arrived. Each routine signals the other to proceed once it has finished its respective work, and loops back and waits for its signal to proceed. In this way, the two tasks execute in an orderly fashion.
The necessary steps for completing exercise 3 are as follows:
Enter the priority of the task to suspend or resume
Report Requirements:
Marking Scheme:
Lab #1 is worth 25% of the final lab mark.Last modified September 16, 2004