/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2008-2011, Martin Schoeberl (martin@jopdesign.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package javax.safetycritical; import static javax.safetycritical.annotate.Level.LEVEL_1; import static javax.safetycritical.annotate.Level.LEVEL_0; import java.util.Vector; import javax.realtime.AbsoluteTime; import javax.realtime.HighResolutionTime; import javax.realtime.PeriodicParameters; import javax.realtime.PriorityParameters; import javax.realtime.RelativeTime; import javax.safetycritical.annotate.MemoryAreaEncloses; import javax.safetycritical.annotate.SCJAllowed; import javax.safetycritical.annotate.SCJRestricted; import com.jopdesign.sys.Memory; import com.jopdesign.sys.Native; import static javax.safetycritical.annotate.Phase.INITIALIZATION; import joprt.RtThread; /** * The class that represents periodic activity. Should be used as the main * vehicle for real-time applications. * * Now finally we have a class that the implementation can use. * * @author Martin Schoeberl * */ @SCJAllowed public abstract class PeriodicEventHandler extends ManagedEventHandler { PriorityParameters priority; RelativeTime start, period; StorageParameters storage; // ThreadConfiguration tconf; String name; Mission m; Memory privMem; protected RtThread thread; long scopeSize; @MemoryAreaEncloses(inner = { "this", "this", "this" }, outer = { "priority", "parameters", "scp" }) @SCJAllowed @SCJRestricted(phase = INITIALIZATION) public PeriodicEventHandler(PriorityParameters priority, PeriodicParameters release, StorageParameters storage, long scopeSize) { this(priority, release, storage, scopeSize, ""); } @MemoryAreaEncloses(inner = { "this", "this", "this", "this" }, outer = { "priority", "parameters", "scp", "name" }) @SCJAllowed(LEVEL_1) public PeriodicEventHandler(PriorityParameters priority, PeriodicParameters release, StorageParameters storage, long scopeSize, String name) { // TODO: what are we doing with this Managed thing? super(priority, release, storage, name); this.priority = priority; this.storage = storage; this.scopeSize = scopeSize; start = (RelativeTime) release.getStart(); period = release.getPeriod(); // TODO scp // this.tconf = tconf; this.name = name; int p = ((int) period.getMilliseconds()) * 1000 + period.getNanoseconds() / 1000; if (p < 0) { // Overflow p = Integer.MAX_VALUE; } int off = ((int) start.getMilliseconds()) * 1000 + start.getNanoseconds() / 1000; if (off < 0) { // Overflow off = Integer.MAX_VALUE; } m = Mission.getCurrentMission(); if (storage != null) { // Create handler's private memory, except for cyclic executives, where // a single private memory is reused for all handlers. // Mission should not be null at this point, as PEH's are created at // mission initialization. if (!m.isCyclicExecutive) { privMem = new Memory((int) scopeSize, (int) storage.getTotalBackingStoreSize()); } } // No need to create this runnable or a RT thread for cyclic executives // where handler's handleAsyncEvent method is called directly. if (!m.isCyclicExecutive) { final Runnable runner = new Runnable() { @Override public void run() { handleAsyncEvent(); } }; thread = new RtThread(priority.getPriority(), p, off) { public void run() { while (!MissionSequencer.terminationRequest) { privMem.enter(runner); waitForNextPeriod(); } } }; } } @SCJAllowed @SCJRestricted(phase = INITIALIZATION) public final void register() { final Mission m = Mission.getCurrentMission(); if (!m.hasEventHandlers){ // System.out.println("creating MEH vector..."); m.eventHandlersRef = Native.toInt(new Vector()); m.hasEventHandlers = true; } ((Vector) Native.toObject(m.eventHandlersRef)).addElement(this); } /** * Get the actual start time of this handler. The actual start time of the * handler is different from the requested start time (passed at construction * time) when the requested start time is an absolute time that would occur * before the mission has been started. In this case, the actual start time * is the time the mission started. If the actual start time is equal to the * effect start time, then the method behaves as if getResquestedStartTime() * method has been called. If it is different, then a newly created time object * is returned. The time value is associated with the same clock as that used * with the original start time parameter. * * @return a reference to a time parameter based on the clock used to start * the timer. */ @SCJAllowed(LEVEL_1) public HighResolutionTime getActualStartTime() { return null; } /** * Get the effective start time of this handler. If the clock associated * with the start time parameter and the interval parameter (that were * passed at construction time) are the same, then the method behaves as if * getActualStartTime() has been called. If the two clocks are different, * then the method returns a newly created object whose time is the current * time of the clock associated with the interval parameter (passed at * construction time) when the handler is actually started. * * @return a reference based on the clock associated with the interval * parameter. */ @SCJAllowed(LEVEL_1) public HighResolutionTime getEffectiveStartTime() { return null; } /** * Get the last release time of this handler. * * @return a reference to a newly-created javax.safetycritical.AbsoluteTime * object representing this handlers’s last release time, according * to the clock associated with the interval parameter used at * construction time. * @throws IllegalStateException * if this timer has not been released since it was last * started. */ @SCJAllowed(LEVEL_1) public AbsoluteTime getLastReleaseTime() throws IllegalStateException { return null; } /** * Get the time at which this handler is next expected to be released. * * * @return The absolute time at which this handler is expected to be * released in a newly allocated javax.safetycritical.AbsoluteTime * object. The clock association of the returned time is the clock * on which interval parameter (passed at construction time) is * based. * * @throws ArithmeticException * if the result does not fit in the normalized format. Throws * IllegalStateException Thrown if this handler has not been * started. */ @SCJAllowed(LEVEL_1) public AbsoluteTime getNextReleaseTime() throws ArithmeticException { return null; } /** * Get the requested start time of this periodic handler. Note that the * start time uses copy semantics, so changes made to the value returned by * this method will not effect the requested start time of this handler if * it has not already been started. * * @return a reference to the start time parameter in the release parameters * used when constructing this handler. */ @SCJAllowed(LEVEL_1) public HighResolutionTime getRequestedStartTime() { return null; } /** * Get the time at which this handler is next expected to be released. * * @param dest * The instance of javax.safetycritical.AbsoluteTime which will * be updated in place and returned. The clock association of the * dest parameter is ignored. When dest is null a new object is * allocated for the result. * * @return the instance of javax.safetycritical.AbsoluteTime passed as * parameter, with time values representing the absolute time at * which this handler is expected to be released. If the dest * parameter is null the result is returned in a newly allocated * object. The clock association of the returned time is the clock * on which the interval parameter (passed at construction time) is * based. * * @throws ArithmeticException * If the result does not fit in the normalized format. * * @throws IllegalStateException * If this handler has not been started. */ @SCJAllowed(LEVEL_1) public AbsoluteTime getnextReleaseTime(AbsoluteTime dest) throws ArithmeticException, IllegalStateException { return null; } /** * Not on spec, implementation specific */ long getScopeSize(){ return this.scopeSize; } }