Source code for olaf.board.pru

"""Quick class to control an Octavo A8's PRU"""

from enum import Enum, auto
from os.path import basename, isdir, isfile


[docs] class PruState(Enum): """All the states a Pru can be in.""" OFFLINE = auto() """PRU is offline""" RUNNING = auto() """PRU is online and running"""
[docs] class PruError(Exception): """Raised when a error occurs with a PRU."""
[docs] class Pru: """ Handles interterations with a PRU on Octavo A8. A PRU is Programible Real-time Unit. It's a microcontroller that shares pins and other resources with the core processor. """ def __init__(self, pru_num: int): """ Parameters ---------- pru_num: int PRU number. Must be a 0 or 1. Raises ------ PruError `pru` was not set to 0 or 1 or if the firmware file does not exist. """ if pru_num not in [0, 1]: raise PruError(f"pru must be set 0 or 1, not {pru_num}") self._pru_num = pru_num # remoteproc0 is the power manager M3 self._pru_dir_path = f"/dev/remoteproc/pruss-core{pru_num}" self._pru_state_path = self._pru_dir_path + "/state" self._pru_fw_path = self._pru_dir_path + "/firmware"
[docs] def start(self): """ Starts the PRU. Raises ------ PruError The PRU or PRU firmware was not found. """ if self.state == PruState.RUNNING: return # already running self.exists(raise_exception=True) with open(self._pru_state_path, "w") as f: f.write("start")
[docs] def stop(self): """ Stops the PRU. Raises ------ PruError The PRU was not found. """ self.exists(raise_exception=True) # The state file will throw an errno 22 if a 'stop' command is writen to it while the # state is 'offline' if self.state == PruState.RUNNING: with open(self._pru_state_path, "w") as f: f.write("stop")
[docs] def restart(self): """Restarts the PRU.""" self.stop() self.start()
@property def state(self) -> PruState: """PruState: The state of the PRU.""" self.exists(raise_exception=True) with open(self._pru_state_path, "r") as f: state = f.read()[:-1] # drop the NULL terminator return PruState[state.upper()]
[docs] def exists(self, raise_exception: bool = False) -> bool: """Check if the PRU exists. Parameters ---------- raise_exception: bool Raises :py:class:`PruError` if PRU is not found. Raises ------ PruError Raised when `raise_exception` was set to `True` and the PRU was not found. Returns ------- bool True if the PRU exists or False if not found. """ ret = isdir(self._pru_dir_path) if raise_exception and not ret: raise PruError(f"pru{self._pru_num} was not found. is the PRU device tree loaded?") return ret
@property def firmware(self) -> str: """str: Firmware file name selected. Must be in `/lib/firmware/`.""" with open(self._pru_fw_path, "r") as f: fw_file = f.read()[:-1] # drop the NULL terminator return fw_file @firmware.setter def firmware(self, fw_path: str): if self.state != PruState.OFFLINE: raise PruError(f"PRU{self._pru_num} must be in OFFLINE state to set firmware") if not (isfile(fw_path) or isfile("/lib/firmware/" + fw_path)): raise PruError(f"firmware image {fw_path} not found") # path must not include "/lib/firmware/" if fw_path.startswith("/lib/firmware/"): fw_path = basename(fw_path) with open(self._pru_fw_path, "w") as f: f.write(fw_path)