Source code for pynq.devicetree

#   Copyright (c) 2016, Xilinx, Inc.
#   All rights reserved.
#
#   Redistribution and use in source and binary forms, with or without
#   modification, are permitted provided that the following conditions are met:
#
#   1.  Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#
#   2.  Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#
#   3.  Neither the name of the copyright holder nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#   OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os

__author__ = "Yun Rock Qu"
__copyright__ = "Copyright 2019, Xilinx"
__email__ = "pynq_support@xilinx.com"


SYSTEM_DEVICE_TREE_PATH = '/sys/kernel/config/device-tree/overlays'


[docs]def get_dtbo_path(bitfile_name): """This method returns the path of the dtbo file. For example, the input "/home/xilinx/pynq/overlays/base/base.bit" will lead to the result "/home/xilinx/pynq/overlays/base/base.dtbo". Parameters ---------- bitfile_name : str The absolute path of the bit file. Returns ------- str The absolute path of the dtbo file. """ return ''.join(bitfile_name.split('.', -1)[:-1]) + '.dtbo'
[docs]def get_dtbo_base_name(dtbo_path): """This method returns the base name of the dtbo file. For example, the input "/home/xilinx/pynq/overlays/name1/name2.dtbo" will lead to the result "name2". Parameters ---------- dtbo_path : str The absolute path of the dtbo file. Returns ------- str The base name of the dtbo file. """ return dtbo_path.split('/')[-1].split('.')[0]
[docs]class DeviceTreeSegment: """This class instantiates the device tree segment object. Attributes ---------- dtbo_name : str The base name of the dtbo file as a string. dtbo_path : str The absolute path to the dtbo file as a string. """ def __init__(self, dtbo_path): """Return a new DeviceTreeSegment object. Parameters ---------- dtbo_path : str The absolute path to the dtbo file as a string. """ if not os.path.isfile(dtbo_path): raise IOError('The dtbo file {} does not exist.'.format(dtbo_path)) self.dtbo_path = dtbo_path self.dtbo_name = get_dtbo_base_name(dtbo_path) self.sysfs_dir = os.path.join(SYSTEM_DEVICE_TREE_PATH, self.dtbo_name)
[docs] def is_dtbo_applied(self): """Show if the device tree segment has been applied. Returns ------- bool True if the device tree status shows `applied`. """ if not os.path.exists(self.sysfs_dir): return False with open(os.path.join(self.sysfs_dir, 'status'), 'r') as f: return f.read() == 'applied\n'
[docs] def insert(self): """Insert the dtbo file into the device tree. The method will raise an exception if the insertion has failed. """ os.makedirs(self.sysfs_dir, exist_ok=True) with open(self.dtbo_path, 'rb') as f: dtbo_data = f.read() with open(os.path.join(self.sysfs_dir, 'dtbo'), 'wb', buffering=0) as f: f.write(dtbo_data) if not self.is_dtbo_applied(): raise RuntimeError('Device tree {} cannot be applied.'.format( self.dtbo_name))
[docs] def remove(self): """Remove the dtbo file from the device tree. """ if os.path.exists(self.sysfs_dir): os.rmdir(self.sysfs_dir)