RT Java Slides
Download
Report
Transcript RT Java Slides
Real-Time Java
Real-Time Systems
Anders P. Ravn
Aalborg University
March 2008
Time
HighResolutionTime
AbsoluteTime
RelativeTime
RationalTime
RTSJ HighResolutionTime
public abstract class HighResolutionTime implements
java.lang.Comparable
{
public abstract AbsoluteTime absolute(Clock clock,
AbsoluteTime destination);
public abstract RelativeTimeTime relative(Clock clock,
RelativeTime destination);
...
public boolean equals(HighResolutionTime time);
public final long getMilliseconds();
public final int getNanoseconds();
public void set(HighResolutionTime time);
public void set(long millis);
public void set(long millis, int nanos);
}
RTSJ AbsoluteTime
public class AbsoluteTime extends HighResolutionTime
{
// various constructor methods including
public AbsoluteTime(AbsoluteTime T);
public AbsoluteTime(long millis, int nanos);
public
...
public
...
public
public
...
public
}
AbsoluteTime absolute(Clock clock, AbsoluteTime dest);
final AbsoluteTime add(RelativeTime time);
final RelativeTime subtract(AbsoluteTime time);
final AbsoluteTime subtract(RelativeTime time);
void set(java.util.Date date)
Clocks in Java
• Similar to those in Ada
• java.lang.System.currentTimeMillis
returns the number of milliseconds since
1/1/1970 GMT and is used by
java.util.Date
RTSJ RelativeTime
public class RelativeTime extends HighResolutio
{
// various constructor methods including
public RelativeTime(long millis, int nanos);
public RelativeTime(RelativeTime time);
public AbsoluteTime absolute(Clock clock,
AbsoluteTime destination);
public final RelativeTime add(RelativeTime time);
public final RelativeTime subtract(RelativeTime time);
}
RTSJ RationalTime
public class RationalTime extends RelativeTime
Deprecated. As of RTSJ 1.0.1
An object that represents a time interval milliseconds/103 + nanoseconds/109 seconds long
that is divided into subintervals by some frequency.
This is generally used in periodic events, threads, and feasibility analysis to specify periods
where there is a basic period that must be adhered to strictly (the interval),
but within that interval the periodic events are supposed to happen frequency times,
as uniformly spaced as possible, but clock and scheduling jitter is moderately acceptable.
Caution: This class is explicitly unsafe in multithreaded situations when it is being changed.
No synchronization is done.
It is assumed that users of this class who are mutating instances will be doing their own
synchronization at a higher level.
RTSJ Clock
public abstract class Clock
{
public Clock();
public static Clock getRealtimeClock();
public abstract RelativeTime getEpochOffset();
public abstract RelativeTime getResolution();
public AbsoluteTime getTime();
public abstract void getTime(AbsoluteTime time);
public abstract void setResolution(RelativeTime resolution);
}
RTSJ Timer
AsyncEvent
Timer
OneShotTimer
PeriodicTimer
RTSJ AsyncEvent
public class AsyncEvent
{
public AsyncEvent();
public void addHandler(AsyncEventHandler handler);
...
}
An asynchronous event can have a set of handlers associated with it,
and when the event occurs,
the fireCount of each handler is incremented,
and the handlers are released.
RTSJ Timer
public abstract class Timer
{
protected Timer(HighResolutionTime time,
Clock clock,
AsyncEventHandler handler);
...
public void enable();
public void disable();
...
public AbsoluteTime getFireTime(AbsoluteTime dest);
public void fire();
Should not be called.
The fire method is reserved for the use of the timer.
}
RTSJ ReleaseParameters
ReleaseParameters
PeriodicParameters
AperiodicParameters
SporadicParameters
RTSJ ReleaseParameters
public abstract class ReleaseParameters {
protected ReleaseParameters(
RelativeTime cost, RelativeTime deadline,
AsyncEventHandler overrunHandler,
AsyncEventHandler missHandler);
...
public RelativeTime getCost();
public AsyncEventHandler getCostOverrunHandler();
public RelativeTime getDeadline();
public AsyncEventHandler getDeadlineMissHandler();
// methods for setting the above
}
RTSJ Periodic Parameters
public class PeriodicParameters extends ReleaseParameters
{
public PeriodicParameters(
HighResolutionTime start,
RelativeTime period,
RelativeTime cost,
RelativeTime deadline,
AsyncEventHandler overrunHandler,
AsyncEventHandler missHandler);
public
public
public
public
}
RelativeTime getPeriod();
HighResolutionTime getStart();
void setPeriod(RelativeTime period);
void setStart(HighResolutionTime start);
RTSJ Aperiodic- and SporadicParameters
public class AperiodicParameters extends ReleaseParameters
{
public AperiodicParameters(RelativeTime cost,
RelativeTime deadline, AsyncEventHandler overrunHandler,
AsyncEventHandler missHandler);
}
public class SporadicParameters extends AperiodicParameters
{
public SporadicParameters(RelativeTime minInterarrival,
RelativeTime cost, RelativeTime deadline,
AsyncEventHandler overrunHandler,
AsyncEventHandler missHandler);
public RelativeTime getMinimumInterarrival();
public void setMinimumInterarrival(RelativeTime minimum);
}
RTSJ SchedulingParameters
SchedulingParameters
PriorityParameters
ImportanceParameters
RTSJ SchedulingParameters
public class PriorityParameters {
public PriorityParameters(int priority);
...
}
public class ImportanceParameters {
public PriorityParameters(int priority, int importance);
...
}
Importance is an additional scheduling metric that may be used by
some priority-based scheduling algorithms
during overload conditions to differentiate execution order
among threads of the same priority.
RTSJ Scheduler
Scheduler
PriorityScheduler
Class which represents the required (by the RTSJ)
priority-based scheduler.
The default instance is the base scheduler which does
fixed priority, preemptive scheduling.
RTSJ PriorityScheduler
public class PriorityScheduler extends Scheduler
{
public static PriorityScheduler instance();
...
protected boolean
addToFeasibility(Schedulable schedulable);
public boolean isFeasible();
public boolean SetIfFeasible(
Schedulable schedulable,
ReleaseParameters release,
MemoryParameters memory);
}
RTSJ Schedulable
«interface»
Schedulable
AsyncEventHandler
RealTimeThread
BoundAsyncEventHandler
NoHeapRealTimeThread
RTSJ AsyncEventHandler
public class AsyncEventHandler extends java.lang.Object
implements Schedulable
{
public AsyncEventHandler(
SchedulingParameters scheduling,
ReleaseParameters release,
MemoryParameters memory, MemoryArea area,
boolean nonheap);
...
public void handleAsyncEvent();
// the program to be executed
...
protected int getAndClearPendingFireCount();
}
RTSJ RealTimeThread
public class RealtimeThread extends java.lang.Thread
implements Schedulable
{
public RealtimeThread(SchedulingParameters s, ReleaseParameters r);
. . .
// methods for implementing the Schedulable interface
public synchronized void addToFeasibility();
. . .
public static RealtimeThread currentRealtimeThread();
public synchronized void schedulePeriodic();
// add the thread to the list of schedulable objects
public synchronized void deschedulePeriodic();
// remove the thread from the list of schedulable object
// when it next issues a waitForNextPeriod
public boolean waitForNextPeriod() throws ...;
public synchronized void interrupt();
// overrides java.lang.Thread.interrupt()
public static void sleep(Clock c, HighResolutionTime time) throws ...;
}
RTSJ Periodic
public class Periodic extends RealtimeThread
{
public Periodic( PriorityParameters PP,
PeriodicParameters P)
{ ... };
public void run()
{
while(true) {
// code to be run each period
...
waitForNextPeriod();
}
}
}
RTSJ Periodic Example
{
AbsoluteTime
A = new AbsoluteTime(...);
PeriodicParameters P = new PeriodicParameters(
A,
new RelativeTime(10,0),
new RelativeTime(1,0),
new RelativeTime(5,0),
null, null );
PriorityParameters PP = new PriorityParameters(...);
Periodic ourThread = new Periodic(PP, P); //create thread
ourThread.start(); // release it
}
RTSJ Memory Management
MemoryArea
«singleton»
HeapMemory
ScopedMemory
ImmortalMemory
LTMemory
ImmortalPhysicalMemory
VTMemory
RTSJ MemoryArea
public abstract class MemoryArea {
protected MemoryArea(long sizeInBytes);
public void enter(java.lang.Runnable logic);
// associate this memory area to the current thread
// for the duration of the logic.run method
public static MemoryArea getMemoryArea(java.lang.Object object);
// get the memory area associated with the object
public long memoryConsumed();
// number of bytes consumed in this memory area
public long memoryRemaining();
// number of bytes remaining
. . .
public synchronized java.lang.Object newInstance(
java.lang.Class type)throws IllegalAccessException,
InstantiationException, OutOfMemoryError;
// allocate an object
public long size(); // the size of the memory area
}
Immortal Memory
• Immortal memory is shared among all threads in
an application
• Objects created in immortal memory are never
subject to garbage collection and are freed only
when the program terminates
public final class ImmortalMemory
extends MemoryArea
{
public static ImmortalMemory
instance();
}
Scoped Memory
• A memory area where objects which have a well-defined lifetime
• May be entered explicitly (by the use of the enter method) or
implicitly by attaching it to a RealtimeThread at thread
creation time
• Associated with each scoped memory is a reference count which
incremented for every call to enter and at every associated thread
creation
• It is decremented when the enter method returns and at every
associated thread exit
• When the reference count reaches 0, all objects resident in the
scoped memory have their finalization method executed and the
memory is reclaimed
• Scoped memory can be nested by nested calls to enter
Scoped Memory
public abstract class ScopedMemory extends MemoryArea
{
public ScopedMemory(long size);
public void enter(java.lang.Runnable logic);
public int getMaximumSize();
public MemoryArea getOuterScope();
public java.lang.Object getPortal();
public void setPortal(java.lang.Object object);
}
Scoped Memory
• The ScopedMemory class which has several subclasses
– VTMemory: allocations may take variable amounts of time
– LTMemory: allocations occur in linear time (related to the size of the
object)
– ScopedPhysicalMemory: allowing objects to be allocated at physical
memory locations
• To avoid the possibility of dangling pointers, a set of access restrictions are
placed on the use of the various memory areas
– Heap objects -- can reference other heap objects and objects in immortal
memory only (i.e. it cannot access scoped memory)
– Immortal objects -- can reference heap objects and immortal memory
objects only;
– Scoped objects -- can reference heaped objects, immortal objects and
objects in the same scope or an outer scope only
Example
import javax.realtime.*;
public class ThreadCode implements Runnable
{
private void computation()
{
final int min = 1*1024;
final int max = 1*1024;
final LTMemory myMem = new LTMemory(min, max);
myMem.enter(new Runnable()
{
public void run()
{
// code here which requires access
// to temporary memory
}
} );
}
Example
public void run()
{
...
computation();
...
}
}
• The thread can now be created; note, no
parameters other than the memory area and the
Runnable are given
ThreadCode code = new ThreadCode();
RealtimeThread myThread = new RealtimeThread(
null, null, null, ImmortalMemory.instance(),
null, code);
Stack Management
• Embedded programmers also have to be concerned with stack
size
• Specifying the stack size of a task/thread requires trivial support
(for example, in Ada it is via the Storage_Size attribute
applied to a task; in POSIX it is via pthread attributes)
• Calculating the stack size is more difficult; as tasks enter blocks
and execute procedures their stacks grow
• To estimate the maximum extent of this growth requires
knowledge of the execution behaviour of each task
• This knowledge is similar to that required to undertake WCET
analysis
• WCET and worst-case stack usage bounds can be obtained from
control flow analysis of the task's code
RTSJ Memory Access
• RTSJ allows access to memory mapped
device registers via the concept of raw
memory
• An implementation is allowed to support a
range of memory types, e.g. DMA, shared
memory, IO_Page
public class RawMemoryAccess {
protected RawMemoryAccess(long base, long size);
protected RawMemoryAccess(RawMemoryAccess memory,
long base, long size);
public static RawMemoryAccess create(
java.lang.Object type, long size)
throws SecurityException, OffsetOutOfBoundsException,
SizeOutOfBoundsException,
UnsupportedPhysicalMemoryException;
public static RawMemoryAccess create(
java.lang.Object type, long base, long size)
throws SecurityException, OffsetOutOfBoundsException,
SizeOutOfBoundsException,
UnsupportedPhysicalMemoryException;
public byte getByte(long offset)
throws SizeOutOfBoundsException, OffsetOutOfBoundsException;
// similarly for integers, long integers, etc
public void setByte(long offset, byte value)
throwsSizeOutOfBoundsException, OffsetOutOfBoundsException;
// similarly for integers, long integers etc
}
Control and Status Register Example
public class ControlAndStatusRegister
{
RawMemoryAccess rawMemory;
public ControlAndStatusRegister(long base, long size)
{
rawMemory = RawMemoryAccess.create(IO_Page, base, size);
}
public void setControlWord(short value)
{
rawMemory.setShort(0, value);
}
};
{
Using the CSR
byte shadow, channel;
final byte start = 01;
final byte enable = 040;
final long csrAddress = 015002;
final long csrSize = 2;
ControlAndStatusRegister csr = new
ControlAndStatusRegister(csrAddress, csrSize);
channel = 6;
shadow = (channel << 8) | start | enable;
csr.setControlWord(shadow);
}
Interrupt Handling
• RTJ views an interrupt as an asynchronous event
• The interrupt is equivalent to a call of the fire method
• The association between the interrupt and the event is achieved via
the bindTo method in the AsyncEvent class
• The parameter is of string type, and this is used in an
implementation-dependent manner — one approach might be to
pass the address of the interrupt vector
• When the interrupt occurs, the appropriate handler's fire method is
called
• Now, it is possible to associate the handler with a schedulable object
and give it an appropriate priority and release parameters
Interrupt Handling
AsyncEvent Interrupt = new AsyncEvent();
AsyncEventHandler InterruptHandler = new
BoundAsyncEventHandler(
priParams, releaseParams, null, null, null);
Interrupt.addHandler(InterruptHandler);
Interrupt.bindTo(”0177760");
Ravenscar Periodic Thread
«interface»
Runnable
+run() : void
Thread
MemoryArea
«interface»
Schedulable
-End2
1
-End2
PriorityParameters
1
RealtimeThread
-End1
-End1
-End1
-End1
11
1
1
-End2
1
-End2
1
NoHeapRealTimeThread
Initializer
PeriodicThread
-aJileTh : com.ajile.jem.PeriodicThread
PeriodicParameters
«interface»
Runnable
+run() : void
Asynchronous Event and Handler
«interface»
Runnable
+run()
«interface»
Schedulable
AsyncEvent
AsyncEventHandler
#bindTo(in happening : String)
#addHandler(in handler : AsyncEventHandler)
#fire()
#handleAsyncEvent()
+run()
-End1 NoHeapRealTimeThread
BoundAsyncEventHandler -End2
1 1
SporadicEvent
+fire()
uses
SporadicInterrupt
uses
SporadicEventHandler
+handleAsyncEvent()
-End2
-End1 RelativeTime
1
1