CS452 - Real-Time Programming - Fall 2011

Lecture 14 - Task Structure, Debugging

Public Service Annoucements

  1. Due date of kernel 3 (Monday, 17 October)
  2. There are two daisy-chained ICUs
  3. Kernel 2 results

Clock Server, Task Structure

A New Kernel Primitive: int AwaitEvent( int EventType )

Argument

  1. Somewhere there is a list of event types
  2. This is not very portable

Strategy for Handling Hardware Interrupts

Implementation Decision

  1. What should be done if there is an existing interrupt when AwaitEvent is called?

HALT versus an Idle Task

What do you do when there are no tasks to run?

You should use an idle task, created during kernel initialization.


Clock Server

Primitives

int Time( int tid )
int Delay( int ticks, int tid )
int DelayUntil( int ticks, int tid )

Why is the tid needed as an argument?

There is no swi instruction in these wrapper programs.

Implementation

main( ) {
    notifier = Create( HIGHEST, ... );
    time = 0
    Send( notifier, &evtType, ... );
    FOREVER {
        Receive( &requester, &request, ... );
        switch ( request.type ) {
        case NOTIFIER:
            Reply( notifier, ... )
            time++;
            break;
        case TIME_REQUEST:
            Reply( requester, time,... )
            break;
        case DELAY_REQUEST: 
            Add requester to list of suspended tasks
            break;
        }
        Check list of suspended tasks and reply
    }
}

Comments:

  1. You need a common request type, or possibly a union.
  2. You should notice a typical server pattern.

It's normal to sort the list of suspended tasks. Why?


Debugging Real-time Programs

The most common set of debugging tools used by experienced programmers is the oldest: printf, grep & stack trace.

Debugging real-time programs, at its base, is just the same as any other debugging, and just the same as empirical science.

  1. Gather data.
  2. Create a model that explains the data
  3. Test the model
  4. If the model is not correct, go to 1.
  5. Remember that the model is ALWAYS provisional: data collected later may invalidate it, no matter how much data has confirmed it.

But real-time programs are harder to debug. Very few programs are entirely free of critical races, which are the worst type of bug, lurking for weeks months or years in seemingly correct code, the appearing when innocuous, unconnected changes occur.

RedBoot

The memory contents are not wiped by reset. Some of the most difficult errors can be detected only by using the contents of memory after a reset.

On some types of exceptions RedBoot will attempt to connect with gdb. In such cases it writes a bunch of gibberish on the bottom of the monitor screen. Among that gibberish is the address of the instruction that caused the exception. Using the load map generated by the linker you can find

It is usually pretty easy to figure out which line of C source was responsible for the instruction.

Stack Trace

In single-threaded programs this is often the most useful tool.

What is the equivalent of a stack trace in a real-time multi-tasking environment?

Breakpoint

What does it do?

How do you get it started?

Breakpoint is a special case of a particular sort of tool that is very common.

Getting information closer to real-time.


Return to: