Source code for pyvar.cm.core
# Copyright 2022 Variscite LTD
# SPDX-License-Identifier: BSD-3-Clause
"""
:platform: Unix/Yocto
:synopsis: Class to handle Cortex-M applications.
.. moduleauthor:: Alifer Moraes <alifer.m@variscite.com>
"""
import subprocess
import sys
import serial
from .utils.helper import *
[docs]
class CortexM:
"""
:ivar module: SoM type;
:ivar core: Cortex-M core being used;
:ivar tty_rpmsg: virtual port to communicate with rpmsg applications;
:ivar firmwares: list all the available Cortex-M firmwares;
"""
def __init__(self, core_n=0, tty_offset=3):
"""
Constructor method for the Cortex-M class.
"""
self.module = get_module()
self._validate_cm()
self._validate_firmwares()
self._num_cores = get_cm_cores(self.module)
self.core = core_n
self.tty_rpmsg = CM_TTY.format(tty_offset, self.core)
self._firmware_path = CM_FIRMWARE.format(self.core)
self._state_path = CM_STATE.format(self.core)
def __del__(self):
"""
Destructor method for the Cortex-M class.
"""
try:
self._stop()
except AttributeError:
pass
@property
def core(self):
"""
Get which Cortex-M core is being used.
Returns:
An integer representing the Cortex-M core.
"""
return self._core
@core.setter
def core(self, core_n):
"""
Set which Cortex-M core is going to be used.
Args:
core_n (int): index of the Cortex-M core.
"""
if core_n >= self._num_cores:
self._core = 0
else:
self._core = core_n
@property
def state(self):
"""
Get the current Cortex-M state.
Returns:
A string containing the Cortex-M state.
"""
if os.path.isfile(self._state_path):
with open(self._state_path, 'r') as f:
return f.read().strip()
return "unavailable"
@state.setter
def state(self, new_state):
"""
Set the Cortex-M state.
Args:
new_state (str): the state the Cortex-M is going to be set.
"""
if (self.state == "offline" and new_state == CM_START) \
or (self.state == "running" and new_state == CM_STOP):
with open(self._state_path, 'w') as f:
f.write(new_state)
@property
def firmware(self):
"""
Get the current Cortex-M firmware.
Returns:
A string containing the Cortex-M firmware.
"""
if os.path.isfile(self._firmware_path):
with open(self._firmware_path, 'r') as f:
return f.read().strip()
return "unavailable"
@firmware.setter
def firmware(self, new_firmware):
"""
Set the Cortex-M firmware.
Args:
new_firmware (str): the firmware that is going
to be loaded into the Cortex-M.
"""
if os.path.isfile(self._firmware_path):
with open(self._firmware_path, 'w') as f:
f.write(new_firmware)
[docs]
def run(self, firmware):
"""
Run a given firmware into the Cortex-M.
Args:
firmware (str): the firmware that is going
to run into the Cortex-M.
"""
if firmware in self.firmwares:
self._stop()
self._load(firmware)
self._start()
else:
print(f"{firmware} is not a valid Cortex-M app.")
[docs]
def write(self, message):
"""
Send a message to a Cortex-M application via virtual serial port.
Args:
message (str): message the is going to be sent.
"""
if os.path.exists(self.tty_rpmsg):
with serial.Serial(self.tty_rpmsg) as ser:
msg_len = ser.write(f"{message}\n".encode())
msg = ser.readline(msg_len).decode().strip()
print(f"Message read from Cortex-M: {msg}")
else:
print(f"Device not found: {self.tty_rpmsg}.")
[docs]
def read(self):
"""
Reads a message from a Cortex-M application via virtual serial port.
"""
if os.path.exists(self.tty_rpmsg):
with serial.Serial(self.tty_rpmsg, timeout=10) as ser:
msg = ser.readline().decode().strip()
print(f"Message read from Cortex-M: {msg}")
else:
print(f"Device not found: {self.tty_rpmsg}.")
def _validate_cm(self):
"""
Checks if Cortex-M is available.
"""
if not is_cm_enabled():
sys.exit(f"Error: {CM_REMOTEPROC_DIR} not found.\n"
f"Please enable remoteproc driver.\n"
f"Most likely you need to use the correct"
f" device tree, try to run:\n"
f"fw_setenv fdt_file {get_cm_dtb(self.module)}"
f" && reboot")
def _validate_firmwares(self):
"""
Checks which files in the firmware directory
are valid Cortex-M firmwares.
"""
self.firmwares = []
firmwares_list = list_firmwares()
if self.module == 'dart' or self.module == 'som':
for firmware in firmwares_list:
if self.module in firmware.lower():
self.firmwares.append(firmware)
def _start(self):
"""
Start the Cortex-M application and loads
the imx_rpms_tty kernel module.
"""
self.state = CM_START
subprocess.run(['modprobe', 'imx_rpmsg_tty'])
def _load(self, firmware):
"""
Set the Cortex-M firmware.
Args:
firmware (str): the firmware that is
going to be loaded into the Cortex-M.
"""
self.firmware = firmware
def _stop(self):
"""
Stop the Cortex-M application and removes
the imx_rpms_tty kernel module.
"""
self.state = CM_STOP
subprocess.run(['modprobe', 'imx_rpmsg_tty', '-r'])