However, the basic Plugin class only provides facilities to display and configure the Plugin. To make the Plugin interact with the simulated microcontroller, additional interfaces must be implemented. Which interface needs to be implemented depends on the functions that your Plugin wishes to perform. The interfaces will also decide how much your Plugin slows down the simulator. The following table indicates which interfaces you must implement for different functions.
If your Plugin wishes to: | Implement | Plugin Type |
---|---|---|
Respond to output generated by the microcontroller. | Port Listener | Medium |
Update only when simulation stops - for example the Memory Monitor | Processor Listener | Fast |
Perform actions independantly of the microcontroller's output, but in time with its clock | Clock Listener | Slow |
In addition, if you wish to connect many signals to different port pins, you may wish to use the Port Mapper class.
Note that the Clock Listener interface is recommended for performing actions at the same time as the processor - rather than using a Java thread. This technique slows down simulation a bit more than threading would. However the unpredictable nature of Java threads and the difficulty of providing robust synchronisation with microcontroller activities makes the Clock Listener interface both more portable and more efficient.
Having included the Plugin classes in your classpath, the next step is to inform miSim DE of the new classes. The 'settings.txt' file in the miSim DE directory is a text file that controls various settings of the simulator, including the Available Plugins list. Again, it is probably worth making a backup of this file before editing it. Having made a backup, open the file to edit, and scroll down to the Available Plugins section, which will look something like this:
[available-plugins]
|
To add a new Plugin, simply add another line to this list. Each line lists the name of the Plugin, and the Java class that implements it. If the Plugin is configurable, then the default configuration is given after the class name, separated by a colon (':').
Therefore, if your plugin is in a file 'MyPlugin.java' that compiles to 'MyPlugin.class', and it takes a single port signal from the microcontroller, you might add a line like this:
My New Plugin = MyPlugin:Port A:0
|
This will give the plugin the name 'My New Plugin' and give it a default configuration of 'Port A:0'. Note that Java class names are case sensitive, so be sure to get the class name right in the settings file.
This only adds the Plugin to the list of available Plugins. To use it in miSim DE you would need to use the 'Add New' button on the Plugin Window to add it to the list of Current Plugins before displaying it. To add it to the Current Plugin list when miSim DE starts up, examine the settings file again. There is a section called 'current plugins' which performs exactly this function and may look like this:
[current-plugins]
|
Each line adds a plugin to the current plugin list. The format is to list the name of the Plugin (as defined in the Available Plugins list) and then the display name of the plugin and optionally its configuration string, again separated by a colon (':').
Once these changes are made to the settings.txt file, save it and re-start miSim DE. Your new Plugin should be shown on the current plugins list, ready to use.
The basic outline of a Plugin class is shown here:
|
The superclass constructor sets three member variables 'machineState', 'reader' and 'owner' to the values passed into it. These can then be referenced in any other Plugin methods. In addition the superclass constructor calls the 'init' method shown below to get the Plugin to create its user interface and initialise itself.
The MachineState class is the class that implements the majority of the microcontroller simulation functions. It provides methods for adding and removing listeners, accessing the microcontroller's memory and instructions and other functions. The RobustReaderIF class provides methods for accessing files in a consistent way, independently of whether miSim DE is being run as an Application or Applet.
There are seven methods that you must implement, each of which is shown here:
|
In the init method, the Plugin must create and add any appropriate GUI objects. The Plugin class is an extension of the Java AWT Container class, so any standard AWT calls may be used here. In addition, the basic config is passed as a parameter. If the plugin is configurable, it should process this config, usually by invoking the readConfig method listed below at the appropriate time.
|
The showPlugin method is called when the user clicks 'Show' in the
Plugin Window of miSim DE.
It is also called when the Plugin is closed.
Usually, it should call the Container method 'setVisible(boolean)
'.
If the Plugin implements any of the Listener classes, it should also
ensure that the appropriate add- or remove-listener methods are called
to add the listeners when the Plugin is displayed, or remove them when
it is closed.
|
This method needs only to return the appropriate PLUGIN_ constant to let miSim DE know what sort of configuration the Plugin supports.
|
This method should let miSim DE know what the current configuration string is for this Plugin. When init or readConfig are called to update the Plugin's configuration, they should store the config string if it is sucessfully applied, so that this method can return it when needed.
|
Read config is called when the 'Set' button is clicked in the miSim DE Plugin Window. If the plugin provides its own configuration GUI, it should show it and once the user has completed the changes, return. Otherwise, it should check that the given configuration string is valid and apply it. If the configuration is valid, the method should return null, otherwise, it should return a String that explains what was wrong with the configuration. This method should store the valid configuration string so that the 'getConfig' method above can return it when required.
|
This method only needs to return a string that describes the Plugin and what it does. The message is shown when the Plugin is selected in the Current Plugin list on the miSim DE Plugin Window, or when 'About' is clicked.
|
This method only needs to return a string that describes the format of the configuration string. It is shown when the user clicks 'Help' on the miSim DE Plugin Window. If this Plugin is not configurable, this method can simply return null.
|
The portEvent method is called when the port output changes. The port output is passed in the portBits parameter. The clockCount paramenter indicates the current cpu time in clock cycles - allowing for timing sensitive plugins to work out how they should respond to the output. As an example, the TV Plugin uses this information to derive the video signal timing data. The portId parameter is used to identify which port called the method. If a Plugin can only listen to one port, this can be ignored. Otherwise, this can be compared with the port Ids of the ports that the Plugin listens to. These can be discovered when the Plugin adds itself as a port listener to ports, using the MachineState class's 'addPortListener' methods.
|
When a Plugin adds itself as a port listener, the port calls this method to discover which bits on that specific port the Plugin is interested in. The method should return a bit mask with bits set to one if the equivalent Port bit is read by the listener.
To listen for output, the listener must add itself to the relevant port. This is done through the MachineState class's addPortListener methods, which should be called when the Plugin is made visible. The methods are:
|
These methods provide the means to add the PortListener to a single port, or
to a list of ports. Both methods return a Vector that contain the Port objects
that are now being listened to. The Port class provides various access methods.
As ports are often referred to through their identifiers, one useful method
is 'getIdentifier()
' which returns the integer identifier for that
port.
When the Plugin is closed, or no longer wishes to respond to port events, it must remove itself from the MachineState, using the following method:
|
![]() |
![]() |
![]() |