243 lines
7.1 KiB
Python
243 lines
7.1 KiB
Python
"""
|
|
Board handling
|
|
"""
|
|
import os
|
|
import sys
|
|
import toml
|
|
|
|
__all__ = [
|
|
'board_select',
|
|
'board_command',
|
|
]
|
|
|
|
#---
|
|
# Internal functions
|
|
#---
|
|
|
|
__PROJ_PREFIX__ = f"{os.path.dirname(__file__)}/../../.."
|
|
|
|
def _warning(text):
|
|
print(text, file=sys.stderr)
|
|
|
|
def _board_fetch_info_meta(board_info, board_desc, board):
|
|
""" Fetch and check board meta information
|
|
|
|
@args
|
|
> board_info (dict) - board information
|
|
> board_desc (dict) - board TOML parsed file
|
|
> board (str) - board name
|
|
|
|
@return
|
|
> 0 if success, negative value otherwise
|
|
"""
|
|
if 'meta' not in board_desc:
|
|
_warning(f"board '{board}' : missing meta section")
|
|
return -1
|
|
if 'author' not in board_desc['meta']:
|
|
_warning(f"board '{board}' : missing author names")
|
|
return -2
|
|
if 'description' not in board_desc['meta']:
|
|
_warning(f"board '{board}' : missing description")
|
|
return -3
|
|
board_info['author'] = board_desc['meta']['author']
|
|
board_info['desc'] = board_desc['meta']['description']
|
|
return 0
|
|
|
|
def _board_fetch_info_config(board_info, board_desc, board):
|
|
""" Fetch and check board configuration information
|
|
|
|
@args
|
|
> board_info (dict) - board information
|
|
> board_desc (dict) - board TOML parsed file
|
|
> board (str) - board name
|
|
|
|
@return
|
|
> 0 if success, negative value otherwise
|
|
"""
|
|
if 'config' not in board_desc:
|
|
_warning(f"board '{board}' : missing config section")
|
|
return -1
|
|
board_conf = board_desc['config']
|
|
if 'modules' not in board_conf:
|
|
_warning(f"board '{board}' : missing modules declaration")
|
|
return -2
|
|
if 'drivers' not in board_conf:
|
|
_warning(f"board '{board}' : missing drivers declaration")
|
|
return -3
|
|
mod_prefix = f"{__PROJ_PREFIX__}/kernel/src/modules"
|
|
for mod in board_conf['modules']:
|
|
if not os.path.exists(f"{mod_prefix}/{mod}"):
|
|
_warning(f"{board} : module '{mod}' does not exists, skipped")
|
|
continue
|
|
board_info['config']['modules'].append(mod)
|
|
drv_prefix = f"{__PROJ_PREFIX__}/kernel/src/drivers"
|
|
for drv in board_conf['drivers']:
|
|
drv_path = drv.replace(':', '/')
|
|
if not os.path.exists(f"{drv_prefix}/{drv_path}"):
|
|
_warning(f"{board} : driver '{drv}' does not exists, skipped")
|
|
continue
|
|
board_info['config']['drivers'].append(drv_path)
|
|
if 'install_files' in board_conf:
|
|
for file in board_conf['install_files']:
|
|
file_pathname = f"{__PROJ_PREFIX__}/boards/{board}/{file}"
|
|
if not os.path.exists(file_pathname):
|
|
_warning("{board}: unable to find the file '{file}', skipped")
|
|
continue
|
|
board_info['config']['install_files'].append(file_pathname)
|
|
return 0
|
|
|
|
def _board_fetch_info(board):
|
|
""" Generate all information about a particular board
|
|
|
|
@return
|
|
> a dictionary with all board information : {
|
|
'name' : <board name>,
|
|
'path' : <board absolute path>,
|
|
'config' : {
|
|
'drivers' : <list of driver pseudo-pathname>,
|
|
'modules' : <list of module pseudo-pathname>
|
|
},
|
|
}
|
|
"""
|
|
board_info = {
|
|
'name' : board,
|
|
'path' : f"{__PROJ_PREFIX__}/boards/{board}",
|
|
'author' : 'unknown',
|
|
'desc' : 'unknown',
|
|
'config' : {
|
|
'drivers' : [],
|
|
'modules' : [],
|
|
'install_files' : []
|
|
}
|
|
}
|
|
|
|
# Check board existance
|
|
if not os.path.exists(board_info['path']):
|
|
_warning(f"board '{board}' does not exists, skipped")
|
|
return {}
|
|
board_desc_path = f"{board_info['path']}/board.toml"
|
|
if not os.path.exists(board_desc_path):
|
|
_warning(f"board '{board}' : missing board description, skipped")
|
|
return {}
|
|
|
|
# Try to dump (and tranforms) board information
|
|
with open(board_desc_path, "r", encoding='utf8') as file:
|
|
board_desc = toml.loads(file.read())
|
|
|
|
# check meta board information
|
|
if _board_fetch_info_meta(board_info, board_desc, board) != 0:
|
|
return {}
|
|
|
|
# check board configuration
|
|
if _board_fetch_info_config(board_info, board_desc, board) != 0:
|
|
return {}
|
|
|
|
# return the board information
|
|
return board_info
|
|
|
|
def _board_fetch_available_board():
|
|
""" Fetch all available board
|
|
|
|
@return
|
|
> a list of all available board name
|
|
"""
|
|
# fetch folder information
|
|
board_prefix = f"{__PROJ_PREFIX__}/boards"
|
|
if not (available_list := list(os.walk(board_prefix))):
|
|
return []
|
|
# fetch folder content only
|
|
if not (available_list := available_list[0]):
|
|
return 0
|
|
# fetch directory only
|
|
return available_list[1]
|
|
|
|
def _board_generate_conf(kernconf, board_info):
|
|
""" generate exportable variable information
|
|
|
|
@args
|
|
> kernconf (dict) - kernel configuration
|
|
> board_info (dict) - board information
|
|
|
|
@return
|
|
> nothing
|
|
"""
|
|
bconf = board_info['config']
|
|
kernconf['VXKERNEL_ENABLE_BOARD'] = board_info['name']
|
|
kernconf['VXKERNEL_ENABLE_MODULES'] = bconf['modules']
|
|
kernconf['VXKERNEL_ENABLE_DRIVERS'] = bconf['drivers']
|
|
kernconf['VXKERNEL_INSTALL_EXTRA_FILES'] = bconf['install_files']
|
|
|
|
def _board_display_list(verbose, board_target):
|
|
""" Display board information
|
|
|
|
@args
|
|
> verbose (bool) - display more information
|
|
> board_target (str) - targeted board
|
|
|
|
@return
|
|
> 0 if success, negative value othervise
|
|
"""
|
|
board_list = [board_target]
|
|
if not board_target:
|
|
board_list = _board_fetch_available_board()
|
|
|
|
print(f"\033[1m{'board':<16}{'Authors':<16}Description\033[0m")
|
|
for board in board_list:
|
|
if not (board_info := _board_fetch_info(board)):
|
|
continue
|
|
content = f"{board:<16}{board_info['author']:<16}{board_info['desc']}"
|
|
if verbose:
|
|
fake_kernconf = {}
|
|
_board_generate_conf(fake_kernconf, board_info)
|
|
content += ":\n"
|
|
for item in fake_kernconf.items():
|
|
content += f" {item[0]:<16} = {item[1]}\n"
|
|
print(content)
|
|
|
|
return 0
|
|
|
|
#---
|
|
# Public
|
|
#---
|
|
|
|
def board_select(kernconf, board):
|
|
""" Select a board and generate output information
|
|
|
|
@args
|
|
> kernconf (dict) - kernel configuration information
|
|
> board (str) - argument for the selection
|
|
|
|
@return
|
|
> Nothing, hangout if error. (return are only here for syntax sugar)
|
|
"""
|
|
if not (board_info := _board_fetch_info(board)):
|
|
sys.exit(84)
|
|
return _board_generate_conf(kernconf, board_info)
|
|
|
|
def board_command(argv):
|
|
""" Board-specific handler
|
|
|
|
@arg
|
|
> argv (list,str) - subcommand arguments
|
|
|
|
@return
|
|
> Never
|
|
"""
|
|
if not argv:
|
|
_warning('missing board argument')
|
|
sys.exit(84)
|
|
|
|
board = ''
|
|
verbose = False
|
|
for arg in argv:
|
|
if arg in ['--list', 'list']:
|
|
verbose = False
|
|
elif arg in ['--info', 'info']:
|
|
verbose = True
|
|
else:
|
|
if board:
|
|
_warning(f"{board} already selected, change for '{arg}'")
|
|
board = arg
|
|
|
|
sys.exit(_board_display_list(verbose, board))
|