System Model Configuration

ScEpTIC analysis can emulate the energy consumption and timing of a given system. ScEpTIC allows you to specify and configure the various components of your system through the various classes available in ScEpTIC/emulator/energy. These classes allows you to specify the following elements of your system:

  • Energy Source

  • Energy Harvester

  • Voltage Regulator

  • Energy Buffer

  • MCU

  • Peripherals

  • State Retention Mechanism

  • Custom Circuitry and Devices

  • Timekeeper

The various analysis available in ScEpTIC takes a SystemEnergyModel object as one of the inputs, which represents a container that includes the system components and provides the logic to emulate system energy consumption and timing.

This is a base example to initialize the SystemEnergyModel:

import ScEpTIC
from ScEpTIC.config import ScEpTICConfig
from ScEpTIC.emulator.energy.system_energy_model import SystemEnergyModel
from ScEpTIC.emulator.energy.options import PowerOffCondition
from ScEpTIC.emulator.energy.power_state_event import PowerStateEvent

system_model = SystemEnergyModel()
system_model.set_power_off_condition(PowerOffCondition.POWER_STATE_EVENT)
system_model.add_power_off_event(PowerStateEvent.MCU_OFF)

# Attach here all system model components
# ...
# ...

config = ScEpTICConfig()
config.analysis.add_config("enabled_analysis", "energy")
config.analysis.energy.set_config("system_model", system_model)

We discuss below the various classes you can use to model your system and how you can attach them to the SystemEnergyModel. The methods available to attach components to your system are:

  • attach_energy_buffer(energy_buffer): attaches an energy buffer to the system model

  • attach_energy_harvester(energy_harvester): attaches an energy harvester to the system model

  • attach_energy_source_model(energy_source): attaches an energy source model to the system model

  • attach_mcu(mcu): attaches a MCU energy model to the system model

  • attach_timekeeper(timekeeper): attaches a time keeper to the system model

  • attach_voltage_regulator(voltage_regulator): attaches a voltage regulator to the system model. Note that this is the regulator used by the MCU. Custom components can be connected directly to the energy buffer or to this regulator

  • attach_component(name, component, power_target): attaches attaches a custom component to the system model

  • attach_custom_device(custom_device): attaches a custom device to the system model

  • attach_state_retention_model(state_retention): attaches a system retention model to the system model

Note that you should attach components to the SystemEnergyModel before attaching it to the ScEpTICConfig.

Units

To simplify the readability of configuration parameters, ScEpTIC allows you to specify numbers in a text form with the following multipliers:

Supported Multipliers

Name

Value

T

1000000000000.0

G

1000000000.0

M

1000000.0

K

1000.0

m

0.001

u

0.000001

n

0.000000001

p

0.000000000001

For example, if you want to specify a \(100{\mu}F\) capacitor, you can simply specify its value as 100u ScEpTIC parses this units using functions available in ScEpTIC/emulator/energy/energy_utils.py.

Energy Source

Energy sources models extends the base EnergySourceModel available in ScEpTIC/emulator/energy/energy_source. ScEpTIC offers three types of energy sources: FixedVoltageSource, SyntheticEnergySource, and TimeSeriesEnergySource. Further, you can create your own energy source model by extending EnergySourceModel.

ScEpTIC accounts for harvested energy power limitations by reproducing the energy source voltage and maximum current. For doing so, you may need to specify the resistance of the load used to measure the energy source output voltage using the set_load_resistance(resistance) method. ScEpTIC uses the value of resistance to calculate the maximum current and limits the energy buffer recharge accordingly. You can use the resistance parameter to model different energy dynamics than the one when the energy source was recorded.

FixedVoltageSource

The FixedVoltageSource class models an ambient energy source that supply a constant amount of voltage. You can create a FixedVoltageSource as follows:

from ScEpTIC.emulator.energy.energy_source.fixed_voltage_source import FixedVoltageSource

energy_source = FixedVoltageSource(v)
energy_source.set_load_resistance('30K')

# attach the energy source to the system model
system_model.attach_energy_source_model(energy_source)

where v is the output voltage of the energy source.

Further, FixedVoltageSource provides the set_voltage() method to change the output voltage:

energy_source.set_voltage(v)

where v is the new output voltage of the energy source.

SyntheticEnergySource

The SyntheticEnergySource class models a synthetic ambient energy source that supplies energy only when the device is powered off. You can create a SyntheticEnergySource as follows:

from ScEpTIC.emulator.energy.energy_source.synthetic_energy_source import SyntheticEnergySource

energy_source = SyntheticEnergySource(v)
energy_source.set_load_resistance('30K')

# attach the energy source to the system model
system_model.attach_energy_source_model(energy_source)

where v is the output voltage of the energy source when the device is powered off.

Similarly to FixedVoltageSource, SyntheticEnergySource provides the set_voltage() method to change the output voltage:

energy_source.set_voltage(v)

where v is the new output voltage of the energy source when the device is powered off.

TimeSeriesEnergySource

The TimeSeriesEnergySource reproduces a voltage or power trace collected from a real energy source. You can create a TimeSeriesEnergySource as follows:

from ScEpTIC.emulator.energy.energy_source.time_series_energy_source import TimeSeriesEnergySource

energy_source = TimeSeriesEnergySource(name)
energy_source.set_load_resistance('30K')

# attach the energy source to the system model
system_model.attach_energy_source_model(energy_source)

where name is the name of the energy source. ScEpTIC provides voltage or power traces of real energy sources in a dedicated repo and automatically downloads them into the ScEpTIC/emulator/energy/energy_source/time_series/ directory the first time they are used. ScEpTIC provides the traces of the following sources:

Energy Source Traces

Name

Description

Reference

rf_mementos

Voltage trace of the RF energy source

Used in Mementos experiments

solar_indoor_rest

Voltage trace of a mono-crystalline solar panel attached to a wrist of a person sitting in a desk in the lab

Used in D2VFS experiments

solar_indoor_moving

Voltage trace of a mono-crystalline solar panel attached to a wrist of a person moving in the lab

Used in D2VFS experiments

solar_outdoor_rest

Voltage trace of a mono-crystalline solar panel attached to a wrist of a person sitting in the university campus

Used in D2VFS experiments

solar_outdoor_moving

Voltage trace of a mono-crystalline solar panel attached to a wrist of a person moving in the university campus

Used in D2VFS experiments

bonito_cars_node0

Power trace of Bonito cars dataset (node 0)

Used in Bonito

bonito_cars_node1

Power trace of Bonito cars dataset (node 1)

Used in Bonito

bonito_cars_node2

Power trace of Bonito cars dataset (node 2)

Used in Bonito

bonito_cars_node3

Power trace of Bonito cars dataset (node 3)

Used in Bonito

bonito_cars_node4

Power trace of Bonito cars dataset (node 4)

Used in Bonito

bonito_cars_node5

Power trace of Bonito cars dataset (node 5)

Used in Bonito

bonito_jogging_node0

Power trace of Bonito jogging dataset (node 0)

Used in Bonito

bonito_jogging_node1

Power trace of Bonito jogging dataset (node 1)

Used in Bonito

bonito_jogging_node2

Power trace of Bonito jogging dataset (node 2)

Used in Bonito

bonito_jogging_node3

Power trace of Bonito jogging dataset (node 3)

Used in Bonito

bonito_jogging_node4

Power trace of Bonito jogging dataset (node 4)

Used in Bonito

bonito_office_node0

Power trace of Bonito office dataset (node 0)

Used in Bonito

bonito_office_node1

Power trace of Bonito office dataset (node 1)

Used in Bonito

bonito_office_node2

Power trace of Bonito office dataset (node 2)

Used in Bonito

bonito_office_node3

Power trace of Bonito office dataset (node 3)

Used in Bonito

bonito_office_node4

Power trace of Bonito office dataset (node 4)

Used in Bonito

bonito_stairs_node0

Power trace of Bonito stairs dataset (node 0)

Used in Bonito

bonito_stairs_node1

Power trace of Bonito stairs dataset (node 1)

Used in Bonito

bonito_stairs_node2

Power trace of Bonito stairs dataset (node 2)

Used in Bonito

bonito_stairs_node3

Power trace of Bonito stairs dataset (node 3)

Used in Bonito

bonito_stairs_node4

Power trace of Bonito stairs dataset (node 4)

Used in Bonito

bonito_stairs_node5

Power trace of Bonito stairs dataset (node 5)

Used in Bonito

bonito_washer_node0

Power trace of Bonito washer dataset (node 0)

Used in Bonito

bonito_washer_node1

Power trace of Bonito washer dataset (node 1)

Used in Bonito

bonito_washer_node2

Power trace of Bonito washer dataset (node 2)

Used in Bonito

bonito_washer_node3

Power trace of Bonito washer dataset (node 3)

Used in Bonito

bonito_washer_node4

Power trace of Bonito washer dataset (node 4)

Used in Bonito

For example, you can use the rf_mementos energy source as follows:

from ScEpTIC.emulator.energy.energy_source.time_series_energy_source import TimeSeriesEnergySource

energy_source = TimeSeriesEnergySource('rf_mementos')
energy_source.set_load_resistance('30K')

# attach the energy source to the system model
system_model.attach_energy_source_model(energy_source)

Energy traces have a fixed recording length. When the trace end is reached, ScEpTIC reproduces the TimeSeriesEnergySource from its trace start. This behaviour can be disabled by setting the attribute restart_on_trace_end to False:

energy_source.restart_on_trace_end = False

Bring Your Own Voltage Source You can use your own voltage source by creating a new json file in ScEpTIC/emulator/energy/energy_source/time_series/. The json file must contan a dictionary with the following elements:

{
    # Sampling time
    "sampling_time": "1m",
    # Equivalent resistance of the load used to collect the traces
    # In that case, ScEpTIC uses the energy harvester resistance as circuit load
    "load_resistance": 30000,
    # Multiplier for the measues (e.g. in this case, the measures are in uW)
    "measures_multiplier": '1u',
    # Value type of the trace (power or voltage)
    "measures_type": "power",
    # If the measures are compressed using zlib to reduce space
    "measures_compressed": false,
    # Measures
    "measures": [...]
}

For example, if you want to create a piezo energy source, you need to create the file ScEpTIC/emulator/energy_source/time_series/piezo.json with the following content:

{
    "sampling_time": "1m",
    "load_resistance": 30000,
    "measures_multiplier": none,
    "measures_type": "voltage",
    "measures_compressed": false,
    "measures": [0.5, 0.3, 1.2, 3.1, ...]
}

Next, you can use the new piezo voltage trace as follows:

from ScEpTIC.emulator.energy.energy_source.time_series_energy_source import TimeSeriesEnergySource

energy_source = TimeSeriesEnergySource('piezo')

For further details, you can find examples in ScEpTIC energy sources dedicated repo or check ScEpTIC/emulator/energy_source/time_series/gen_json.py.

Voltage Regulator

Real systems often use voltage regulators to regulate the operating voltage of system components. Therefore, ScEpTIC implements voltage regulator logic and energy models through the VoltageRegulatorModel base class, located in ScEpTIC/emulator/energy/voltage_regulators. In the same file, ScEpTIC implements the logic of step up voltage regulators and step down voltage regulators, through the classes StepUpVoltageRegulatorModel and StepDownVoltageRegulatorModel, respectively.

You can model a voltage regulator by extending StepUpVoltageRegulatorModel or StepDownVoltageRegulatorModel as follows:

from ScEpTIC.emulator.energy.voltage_regulator import StepUpVoltageRegulatorModel

class MyVoltageRegulator(StepUpVoltageRegulatorModel):
    def __init__(self):
        super().__init__()

        self.efficiency = 0.90
        self.i_quiescent = energy_utils.str_to_float('6.5u')
        self.v_min = 0.9

where the attribute efficiency is the average efficiency of the voltage regulator, i_quiescent is its quiescent current, and v_min is the minimum operating voltage for the regulator to work. These parameters can be obtained from components’ datasheet information.

ScEpTIC already implements the model of three commonly used voltage regulators, using their datasheet information: the MAX20361 voltage charge boost regulator, the TPS61322 step up voltage regulator, and the TPS62740 step down voltage regulator. They can be used as follows:

from ScEpTIC.emulator.energy.voltage_regulator.MAX20361 import MAX20361
regulator = MAX20361()

from ScEpTIC.emulator.energy.voltage_regulator.TPS61322 import TPS61322
regulator = TPS61322()

from ScEpTIC.emulator.energy.voltage_regulator.TPS62740x import TPS62740x
regulator = TPS62740x()

Voltage regulators can be attached to any component using the attach_voltage_regulator(regulator) method. Further, you can model your own voltage regulator by extending the VoltageRegulatorModel class.

Finally, you can set the output voltage of any class extending the VoltageRegulatorModel using the set_output_voltage() method, as follows:

regulator.set_output_voltage(3.6)

Energy Harvester

ScEpTIC models energy dynamics using an energy harvester attached to the system model. Therefore, ScEpTIC requires you to attach the energy source to an energy harvester. Once you defined your energy source model, you need to specify an energy harvester. ScEpTIC allows you to model energy harvesters circuitry by extending the EnergyHarvesterModel base class located in ScEpTIC/emulator/energy/energy_harvester. You can set the energy harvester equivalent resistance using the set_equivalent_resistance() method. Further, you can attach an energy source model to an energy harvester using the method attach_energy_source(energy_source).

ScEpTIC already implements three types of energy harvesters: ChargeBoosterEnergyHarvester, VoltageDoublerEnergyHarvester, and GenericEnergyHarvster.

Charge Booster

This type of energy harvester include a charge booster to boost the energy source voltage. To use this energy harvester, you need first to instantiate a voltage regulator or voltage charge booster. Then, you can create a new instance of the ChargeBoosterEnergyHarvester by passing the charge booster and the harvester resistance as parameters.

Here is an example:

from ScEpTIC.emulator.energy.voltage_regulator.MAX20361 import MAX20361
from ScEpTIC.emulator.energy.energy_harvester.charge_booster import ChargeBoosterEnergyHarvester

harvester_resistance = '1'

# create the voltage booster
charge_booster = MAX20361()
charge_booster.set_output_voltage(v_on * 1.015)

# create the energy harvester
energy_harvester = ChargeBoosterEnergyHarvester(charge_booster, harvester_resistance)

# attach energy source to energy harvester
energy_harvester.attach_energy_source(energy_source)

# attach energy harvester to the system model
system_model.attach_energy_harvester(energy_harvester)

Voltage Doubler

This type of energy harvester models a capacitor array that the WISP platform uses to multiply the voltage of low-voltage energy sources. You can create a new instance of the VoltageDoublerEnergyHarvester by passing the number of voltage doublers and the harvester resistance as parameters.

Here is an example:

from ScEpTIC.emulator.energy.energy_harvester.voltage_doubler import VoltageDoublerEnergyHarvester

harvester_resistance = '1'
n_voltage_doublers = 1 # doubles the voltage once

# create the voltage doubler
energy_harvester = VoltageDoublerEnergyHarvester(n_voltage_doublers, harvester_resistance)

# attach energy source to energy harvester
energy_harvester.attach_energy_source(energy_source)

# attach energy harvester to the system model
system_model.attach_energy_harvester(energy_harvester)

Generic Harvester

This is the most simple type of energy harvester, which does not include any circuitry that alter the energy source voltage. You can create a new instance of the GenericEnergyHarvester by passing the the harvester resistance as a parameter.

Here is an example:

from ScEpTIC.emulator.energy.energy_harvester.generic import GenericEnergyHarvester

harvester_resistance = '1'

# create the generic harvester
energy_harvester = GenericEnergyHarvester(harvester_resistance)

# attach energy source to energy harvester
energy_harvester.attach_energy_source(energy_source)

# attach energy harvester to the system model
system_model.attach_energy_harvester(energy_harvester)

Energy Buffer

ScEpTIC implements the model of a capacitor CapacitorModel that you can use as follows:

from ScEpTIC.emulator.energy.buffer.capacitor import CapacitorModel

energy_buffer = CapacitorModel(capacitance, voltage_upper_bound, energy_upper_bound)

# attach the energy buffer to the system model
system_model.attach_energy_buffer(energy_buffer)

where capacitance is the capacitor’s capacitance, voltage_upper_bound is the maximum capacitor’s voltage, and energy_upper_bound is the maximum energy the capacitor can store. Note that you need to specify the value only for voltage_upper_bound or energy_upper_bound, as ScEpTIC will automatically calcualte the other parameter.

For example, to model a \(50{\mu}F\) capacitor that reaches maximum 6V:

from ScEpTIC.emulator.energy.buffer.capacitor import CapacitorModel

energy_buffer = CapacitorModel('50u', 6.0, None)

The CapacitorModel extends the EnergySourceModel base class that models energy buffers. The EnergySourceModel offers a method to set the energy buffer voltage:

energy_buffer.set_voltage(v)

where v is the new voltage of the energy buffer.

Further, you can implement your own energy buffer by extending the EnergyBufferModel base class, located in ScEpTIC/emulator/energy/buffer, and by overriding its methods.

MCU

In principle, ScEpTIC allows you to model the energy consumption of any MCU and its operating modes through the MCUEnergyModel class, located in ScEpTIC/emulator/energy/mcu. ScEpTIC currently implement only MCUs from the MSP430-FR and MSP430-G families of MCUs, through the MSP430FREnergyModel and MSP430GEnergyModel classes. When initializing an MCUEnergyModel, you must provide the MCU model name, if a lookup table for its energy measurement is available, and the instruction cache hit ratio. For example:

from ScEpTIC.emulator.energy.mcu.msp430fr import MSP430FREnergyModel
mcu = MSP430FREnergyModel('msp430fr5969', load_lookup_table=False, instruction_cache_hit_ratio=0.9)

# attach MCU to the system model
system_model.attach_mcu(mcu)


from ScEpTIC.emulator.energy.mcu.msp430g import MSP430GEnergyModel
mcu = MSP430GEnergyModel('msp430g2553', load_lookup_table=False, instruction_cache_hit_ratio=0.9)

# attach MCU to the system model
system_model.attach_mcu(mcu)

ScEpTIC already models and provides the energy consumption of the following MCUs:

  • msp430fr2355

  • msp430fr5043

  • msp430fr5739

  • msp430fr5969

  • msp430g2553

The MCUEnergyModel provides three methods that you can use to setup the MCU:

  • set_frequency(frequency) sets the MCU operating frequency

  • set_target_lpm(lpm_mode) sets the low-power mode used in the simulations

  • set_v_on(v_on) sets the voltage at which the MCU powers on after energy failures

  • set_mcu_state(state) sets the MCU power state (MCUPowerState.ON for on or MCUPowerState.OFF for off)

  • set_adc_state(state) sets the MCU internal ADC state (ADCPowerState.ON for on or ADCPowerState.OFF for off)

For example, you can set the MCU at 16MHz, LPM4 as target low-power mode, 3.6V as power-on voltage, the MCU on, and the ADC off as follows:

from ScEpTIC.emulator.energy.mcu.options import MCUPowerState, ADCPowerState
mcu.set_frequency('16MHz')
mcu.set_target_lpm('LPM4')
mcu.set_v_on(3.6)
mcu.set_mcu_state(MCUPowerState.ON)
mcu.set_adc_state(ADCPowerState.OFF)

Peripherals

ScEpTIC allows you to model various peripheral devices by extending the MCUPeripheral base class, located in ScEpTIC/emulator/energ/mcu_peripheral. ScEpTIC already implement various peripheral devices:

  • 0V7620 camera/image sensor

  • CC1101 radio

  • SGP40 VOC sensor

  • SHT85 Digital temperature and humidity sensor

  • Generic ADC sensors

They can be found in ScEpTIC/emulator/energ/mcu_peripheral.

Peripherals must be attached to the system model as custom components, speficying if they are powered using the voltage regulator or the energy buffer directly:

from ScEpTIC.emulator.energy.options import ComponentVoltageSource

from ScEpTIC.emulator.energy.mcu_peripheral.cc1101 import CC1101Model
from ScEpTIC.emulator.energy.mcu_peripheral.SHT85 import SHT85
from ScEpTIC.emulator.energy.mcu_peripheral.generic_sensor import GenericADCSensorModel
from ScEpTIC.emulator.energy.mcu_peripheral.camera_0V7620 import Camera0V7620Model

# Crate peripherals
radio = CC1101Model()
generic_sensor = GenericADCSensorModel()
camera = Camera0V7620Model()
temperature = SHT85()

# attach peripherals to the system model, using the voltage regulator to power them
system_model.attach_component('cc1101', radio, ComponentVoltageSource.VOLTAGE_REGULATOR)
system_model.attach_component('0V7620', camera, ComponentVoltageSource.VOLTAGE_REGULATOR)
system_model.attach_component('SHT85', temperature, ComponentVoltageSource.VOLTAGE_REGULATOR)

# attach a peripheral to the system model, using the energy buffer to power it
system_model.attach_component('generic_sensor', generic_sensor, ComponentVoltageSource.ENERGY_BUFFER)

External NVM

ScEpTIC allows to model external NVM to cover situations where MCUs lack a directly-addressable and internal NVM. ScEpTIC models external NVMs using the ExternalNVM class, located in ScEpTIC/emulator/energy/mcu_peripheral/external_nvm.py. ExternalNVM initialization requires to supply the memory model as a parameter. ScEpTIC already implement the following NVMs:

  • MB85RC64V (I2C FRAM, 8kBytes)

  • MB85RC256V (I2C FRAM, 32kBytes)

  • MB85RS64V (SPI FRAM, 8kBytes)

Note that ScEpTIC models the overhead of the I2C and SPI communication protocols. External NVM must be attached as custom component.

For example, to initialize a MB85RC64V:

from ScEpTIC.emulator.energy.options import ComponentVoltageSource
from ScEpTIC.emulator.energy.mcu_peripheral.options import MCUPeripheralPowerStateBehaviour
from ScEpTIC.emulator.energy.mcu_peripheral.external_nvm import ExternalNVM
external_fram = ExternalNVM('MB85RC64V')

# Set power state behavior to follow the one of the MCU (on MCU power off, the NVM powers off)
external_fram.set_power_state_behaviour(MCUPeripheralPowerStateBehaviour.FOLLOW_MCU)

# OR set power state behavior to be always on (depeding on NVM minimum operating voltage)
#external_fram.set_power_state_behaviour(MCUPeripheralPowerStateBehaviour.ALWAYS_ON)

# attach NVM to the system model, powering it using the energy buffer
system_model.attach_component('I2C_FRAM', external_fram, ComponentVoltageSource.ENERGY_BUFFER)

State Retention

ScEpTIC models the energy consumption of state-retention approaches, without requiring to implement them in the code. ScEpTIC supports two types of state retentions: InternalNVMCHeckpointEnergyModel for state retention techniques using NVM locations internal/directly addressable from the MCU, and ExternalCheckpointEnergyModel for state retention techniques using NVM locations external to the MCU.

You can instantiate them as follows:

from ScEpTIC.emulator.energy.state_retention.external_checkpoint import ExternalNVMCheckpointEnergyModel
state_retention = ExternalNVMCheckpointEnergyModel()

# attach state retention model to the system model
system_model.attach_state_retention(state_retention)

from ScEpTIC.emulator.energy.state_retention.internal_checkpoint import InternalNVMCheckpointEnergyModel
state_retention = InternalNVMCheckpointEnergyModel()

# attach state retention model to the system model
system_model.attach_state_retention(state_retention)

Note that ExternalNVMCHeckpointEnergyModel requires that the system configuration contains an external NVM.

Custom Devices

ScEpTIC allows you to model the energy consumption and logic of custom external devices through the CustomDevice class, located at ScEpTIC/emulator/custom_devices. Each custom device must extend the CustomDevice base class and override the following methods:

  • def setup(self, system_model) used to setup the circuitry components of the custom device

  • def init() used to initialize the component

  • def run_logic() used to simulate the device logic

ScEpTIC already implement three custom devies: D2VFS, FBTC, and HibernusVoltageMonitor. They are located in a corresponding directory inside ScEpTIC/emulator/custom_devices. You can follow their implementation to understand how to implement your own custom device.

D2VFS

This custom device implements the logic and energy consumption of D2VFS dynamic voltage and frequency scaling circuitry. You can instantiate D2VFS as follows:

from ScEpTIC.emulator.custom_devices.D2VFS import D2VFSSystemModel
d2vfs = D2VFSSystemModel()

# attach custom device to the system model
system_model.attach_custom_device(d2vfs)

FBTC

This custom device implements the logic and energy consumption of FBTC dynamic voltage and frequency scaling circuitry. You can instantiate FBTC as follows:

from ScEpTIC.emulator.custom_devices.FBTC import FBTCSystemModel
fbtc = FBTCSystemModel()

# attach custom device to the system model
system_model.attach_custom_device(fbtc)

Hibernus

This custom device implements the energy consumption of Hibernus. It automatically attaches Hibernus voltage monitor to the system energy model configuration.

You can instantiate this component as follows:

from ScEpTIC.emulator.custom_devices.HibernusVoltageMonitor import HibernusVoltageMonitor
hibernus = HibernusVoltageMonitor()

# attach custom device to the system model
system_model.attach_custom_device(hibernus)

Note that Hibernus behavior is already available in ScEpTIC state-retention mechanisms.

Time Keeper

ScEpTIC supports basic offline timekeeper functionalities, which are implemented in the TimekeeperModel class, located in ScEpTIC/emulator/timekeeper. You can instantiate a timekeeper as follows:

from ScEpTIC.emulator.energy.timekeeper import TimekeeperModel
timekeeper = TimekeeperModel()

# attach time keeper to the system model
system_model.attach_time_keeper(time_keeper)

To access timekeeper data, you can call sceptic_timekeeper_get_time() or sceptic_timekeeper_get_time_us() in your source code. The former gives you the elapsed seconds while the MCU was powered off, whereas the latter gives you the microseconds.

Example of System Model

Here is an example of a system model:

from ScEpTIC.emulator.energy.buffer.capacitor import CapacitorModel
from ScEpTIC.emulator.energy.energy_harvester.charge_booster import ChargeBoosterEnergyHarvester
from ScEpTIC.emulator.energy.energy_source.time_series_energy_source import TimeSeriesEnergySource
from ScEpTIC.emulator.energy.mcu.msp430fr import MSP430FREnergyModel
from ScEpTIC.emulator.energy.mcu.options import MCUPowerState, ADCPowerState
from ScEpTIC.emulator.energy.mcu_peripheral.camera_0V7620 import Camera0V7620Model
from ScEpTIC.emulator.energy.mcu_peripheral.cc1101 import CC1101Model
from ScEpTIC.emulator.energy.options import ComponentVoltageSource
from ScEpTIC.emulator.energy.options import PowerOffCondition
from ScEpTIC.emulator.energy.power_state_event import PowerStateEvent
from ScEpTIC.emulator.energy.state_retention.internal_checkpoint import InternalNVMCheckpointEnergyModel
from ScEpTIC.emulator.energy.system_energy_model import SystemEnergyModel
from ScEpTIC.emulator.energy.timekeeper import TimekeeperModel
from ScEpTIC.emulator.energy.voltage_regulator.MAX20361 import MAX20361

# Configuration params
config = {
    'capacitance': '100u',
    'cap_v_max': 5.0,
    'mcu_v_on': 3.6,
    'mcu_model': 'msp430fr5969',
    'mcu_cache_hit': 0.85,
    'mcu_lpm': 'LPM4',
    'mcu_clock_frequency': '16MHz',
    'energy_source': 'rf_mementos',
    'load_resistance': '30K',
    'harvester_resistance': '1',
}

# RF Energy Source
energy_source = TimeSeriesEnergySource(config['energy_source'])
energy_source.set_load_resistance(config['load_resistance'])
energy_source.restart_on_trace_end = True

# Charge Booster Energy Harvester
charge_booster = MAX20361()
# Voltage 1.5% higher than MCU Von to ensure power on
charge_booster.set_output_voltage(config['mcu_v_on'] * 1.015)
energy_harvester = ChargeBoosterEnergyHarvester(charge_booster, config['harvester_resistance'])
energy_harvester.attach_energy_source(energy_source)

# Energy buffer
energy_buffer = CapacitorModel(config['capacitance'], config['cap_v_max'], None)
# Start with full energy buffer
energy_buffer.set_voltage(config['mcu_v_on'])

# MCU
mcu = MSP430FREnergyModel(config['mcu_model'], instruction_cache_hit_ratio=config['mcu_cache_hit'])
mcu.set_frequency(config['mcu_clock_frequency'])
mcu.set_target_lpm(config['mcu_lpm'])
mcu.set_v_on(config['mcu_v_on'])
mcu.set_mcu_state(MCUPowerState.ON)
mcu.set_adc_state(ADCPowerState.OFF)

# Timekeeper
timekeeper = TimekeeperModel()

# Peripherals
radio = CC1101Model()
camera = Camera0V7620Model()

# System model
system_model = SystemEnergyModel()
system_model.attach_energy_buffer(energy_buffer)
system_model.set_power_off_condition(PowerOffCondition.POWER_STATE_EVENT)
system_model.add_power_off_event(PowerStateEvent.MCU_OFF)
system_model.attach_energy_source_model(energy_source)
system_model.attach_energy_harvester(energy_harvester)
system_model.attach_mcu(mcu)
# Do not use a voltage regulator for the system
system_model.attach_voltage_regulator(None)

system_model.attach_timekeeper(timekeeper)
system_model.attach_component('cc1101', radio, ComponentVoltageSource.ENERGY_BUFFER)
system_model.attach_component('0V7620', camera, ComponentVoltageSource.ENERGY_BUFFER)

# State retention model
state_retention = InternalNVMCheckpointEnergyModel()
system_model.attach_state_retention_model(state_retention)