Implemented parsing for new register-group-instance element in TDF scripts

This commit is contained in:
Nav
2024-02-17 21:44:02 +00:00
parent de096f63f0
commit 7ac54ec259
6 changed files with 157 additions and 24 deletions

View File

@@ -2,7 +2,7 @@
namespace Targets\TargetDescriptionFiles; namespace Targets\TargetDescriptionFiles;
require_once __DIR__ . "/RegisterGroup.php"; require_once __DIR__ . "/RegisterGroup.php";
require_once __DIR__ . "/RegisterGroupReference.php"; require_once __DIR__ . "/RegisterGroupInstance.php";
require_once __DIR__ . "/Signal.php"; require_once __DIR__ . "/Signal.php";
class Peripheral class Peripheral
@@ -12,8 +12,8 @@ class Peripheral
public ?string $moduleKey = null; public ?string $moduleKey = null;
public ?string $moduleName = null; public ?string $moduleName = null;
/** @var RegisterGroupReference[] */ /** @var RegisterGroupInstance[] */
public array $registerGroupReferences = []; public array $registerGroupInstances = [];
/** @var Signal[] */ /** @var Signal[] */
public array $signals = []; public array $signals = [];
@@ -22,21 +22,21 @@ class Peripheral
?string $key, ?string $key,
?string $name, ?string $name,
?string $moduleKey, ?string $moduleKey,
array $registerGroupReferences, array $registerGroupInstances,
array $signals array $signals
) { ) {
$this->key = $key; $this->key = $key;
$this->name = $name; $this->name = $name;
$this->moduleKey = $moduleKey; $this->moduleKey = $moduleKey;
$this->registerGroupReferences = $registerGroupReferences; $this->registerGroupInstances = $registerGroupInstances;
$this->signals = $signals; $this->signals = $signals;
} }
public function getRegisterGroupReference(string $key): ?RegisterGroupReference public function getRegisterGroupInstance(string $key): ?RegisterGroupInstance
{ {
foreach ($this->registerGroupReferences as $reference) { foreach ($this->registerGroupInstances as $instance) {
if ($reference->key === $key) { if ($instance->key === $key) {
return $reference; return $instance;
} }
} }

View File

@@ -0,0 +1,30 @@
<?php
namespace Targets\TargetDescriptionFiles;
require_once __DIR__ . "/Register.php";
class RegisterGroupInstance
{
public ?string $key = null;
public ?string $name = null;
public ?string $registerGroupKey = null;
public ?string $addressSpaceKey = null;
public ?int $offset = null;
public ?string $description = null;
public function __construct(
?string $key,
?string $name,
?string $registerGroupKey,
?string $addressSpaceKey,
?int $offset,
?string $description
) {
$this->key = $key;
$this->name = $name;
$this->registerGroupKey = $registerGroupKey;
$this->addressSpaceKey = $addressSpaceKey;
$this->offset = $offset;
$this->description = $description;
}
}

View File

@@ -9,6 +9,7 @@ use Targets\TargetDescriptionFiles\MemorySegment;
use Targets\TargetDescriptionFiles\MemorySegmentSection; use Targets\TargetDescriptionFiles\MemorySegmentSection;
use Targets\TargetDescriptionFiles\Module; use Targets\TargetDescriptionFiles\Module;
use Targets\TargetDescriptionFiles\Peripheral; use Targets\TargetDescriptionFiles\Peripheral;
use Targets\TargetDescriptionFiles\RegisterGroupInstance;
use Targets\TargetDescriptionFiles\Property; use Targets\TargetDescriptionFiles\Property;
use Targets\TargetDescriptionFiles\PropertyGroup; use Targets\TargetDescriptionFiles\PropertyGroup;
use Targets\TargetDescriptionFiles\Register; use Targets\TargetDescriptionFiles\Register;
@@ -687,26 +688,26 @@ class ValidationService
$failures[] = 'Missing module key'; $failures[] = 'Missing module key';
} }
if (empty($peripheral->registerGroupReferences) && empty($peripheral->signals)) { if (empty($peripheral->registerGroupInstances) && empty($peripheral->signals)) {
$failures[] = 'Empty - no register group references or signals'; $failures[] = 'Empty - no register group instances or signals';
} }
$processedChildKeys = []; $processedChildKeys = [];
foreach ($peripheral->registerGroupReferences as $registerGroupReference) { foreach ($peripheral->registerGroupInstances as $registerGroupInstance) {
$failures = array_merge( $failures = array_merge(
$failures, $failures,
$this->validateRegisterGroupReference( $this->validateRegisterGroupInstance(
$registerGroupReference, $registerGroupInstance,
$peripheral->moduleKey ?? '', $peripheral->moduleKey ?? '',
$tdf $tdf
) )
); );
if ($registerGroupReference->key !== null && in_array($registerGroupReference->key, $processedChildKeys)) { if ($registerGroupInstance->key !== null && in_array($registerGroupInstance->key, $processedChildKeys)) {
$failures[] = 'Duplicate register group reference key ("' . $registerGroupReference->key . '") detected'; $failures[] = 'Duplicate register group instance key ("' . $registerGroupInstance->key . '") detected';
} }
$processedChildKeys[] = $registerGroupReference->key; $processedChildKeys[] = $registerGroupInstance->key;
} }
foreach ($peripheral->signals as $signal) { foreach ($peripheral->signals as $signal) {
@@ -719,6 +720,64 @@ class ValidationService
); );
} }
protected function validateRegisterGroupInstance(
RegisterGroupInstance $registerGroupInstance,
string $moduleKey,
TargetDescriptionFile $tdf
): array {
$failures = [];
if (empty($registerGroupInstance->key)) {
$failures[] = 'Missing key';
}
if (!mb_check_encoding((string) $registerGroupInstance->key, 'ASCII')) {
$failures[] = 'Key contains non ASCII characters';
}
if (str_contains((string) $registerGroupInstance->key, ' ')) {
$failures[] = 'Key contains at least one period space';
}
if (str_contains((string) $registerGroupInstance->key, '.')) {
$failures[] = 'Key contains at least one period (".") character';
}
if (empty($registerGroupInstance->registerGroupKey)) {
$failures[] = 'Missing register group key';
}
if (empty($registerGroupInstance->name)) {
$failures[] = 'Missing name';
}
if ($registerGroupInstance->offset === null) {
$failures[] = 'Missing offset';
} elseif ($registerGroupInstance->offset > 0xFFFFFFFF) {
$failures[] = 'Offset exceeds 32-bit unsigned integer';
}
if (empty($registerGroupInstance->addressSpaceKey)) {
$failures[] = 'Missing address space key';
} elseif ($tdf->getAddressSpace($registerGroupInstance->addressSpaceKey) === null) {
$failures[] = 'Could not find address space "' . $registerGroupInstance->addressSpaceKey
. '" - check address space key';
}
if ($tdf->resolveRegisterGroupInstance($registerGroupInstance, $moduleKey) === null) {
$failures[] = 'Could not resolve register group instance "' . $registerGroupInstance->key
. '" - check register group key ("' . $registerGroupInstance->registerGroupKey . '")';
}
return array_map(
fn (string $failure): string => 'Register group instance (group key: "'
. $registerGroupInstance->registerGroupKey . '") validation failure: ' . $failure,
$failures
);
}
protected function validateSignal(Signal $signal): array protected function validateSignal(Signal $signal): array
{ {
$failures = []; $failures = [];

View File

@@ -14,6 +14,7 @@ use Targets\TargetDescriptionFiles\MemorySegmentSection;
use Targets\TargetDescriptionFiles\MemorySegmentType; use Targets\TargetDescriptionFiles\MemorySegmentType;
use Targets\TargetDescriptionFiles\Module; use Targets\TargetDescriptionFiles\Module;
use Targets\TargetDescriptionFiles\Peripheral; use Targets\TargetDescriptionFiles\Peripheral;
use Targets\TargetDescriptionFiles\RegisterGroupInstance;
use Targets\TargetDescriptionFiles\PhysicalInterface; use Targets\TargetDescriptionFiles\PhysicalInterface;
use Targets\TargetDescriptionFiles\Property; use Targets\TargetDescriptionFiles\Property;
use Targets\TargetDescriptionFiles\PropertyGroup; use Targets\TargetDescriptionFiles\PropertyGroup;
@@ -325,8 +326,8 @@ class FromXmlService
continue; continue;
} }
if ($childNode->nodeName === 'register-group-reference') { if ($childNode->nodeName === 'register-group-instance') {
$output->registerGroupReferences[] = $this->registerGroupReferenceFromElement($childNode); $output->registerGroupInstances[] = $this->registerGroupInstanceFromElement($childNode);
continue; continue;
} }
@@ -356,6 +357,20 @@ class FromXmlService
return $output; return $output;
} }
public function registerGroupInstanceFromElement(DOMElement $element): RegisterGroupInstance
{
$attributes = $this->getNodeAttributesByName($element);
return new RegisterGroupInstance(
$attributes['key'] ?? null,
$attributes['name'] ?? null,
$attributes['register-group-key'] ?? null,
$attributes['address-space-key'] ?? null,
$this->stringService->tryStringToInt($attributes['offset'] ?? null),
$attributes['description'] ?? null
);
}
public function signalFromElement(DOMElement $element): Signal public function signalFromElement(DOMElement $element): Signal
{ {
$attributes = $this->getNodeAttributesByName($element); $attributes = $this->getNodeAttributesByName($element);

View File

@@ -9,6 +9,7 @@ use Targets\TargetDescriptionFiles\MemorySegment;
use Targets\TargetDescriptionFiles\MemorySegmentSection; use Targets\TargetDescriptionFiles\MemorySegmentSection;
use Targets\TargetDescriptionFiles\Module; use Targets\TargetDescriptionFiles\Module;
use Targets\TargetDescriptionFiles\Peripheral; use Targets\TargetDescriptionFiles\Peripheral;
use Targets\TargetDescriptionFiles\RegisterGroupInstance;
use Targets\TargetDescriptionFiles\PhysicalInterface; use Targets\TargetDescriptionFiles\PhysicalInterface;
use Targets\TargetDescriptionFiles\Pin; use Targets\TargetDescriptionFiles\Pin;
use Targets\TargetDescriptionFiles\Pinout; use Targets\TargetDescriptionFiles\Pinout;
@@ -135,8 +136,8 @@ class ToXmlService
$element->setAttribute('name', $peripheral->name); $element->setAttribute('name', $peripheral->name);
$element->setAttribute('module-key', $peripheral->moduleKey); $element->setAttribute('module-key', $peripheral->moduleKey);
foreach ($peripheral->registerGroupReferences as $registerGroupReference) { foreach ($peripheral->registerGroupInstances as $registerGroupInstance) {
$element->append($this->registerGroupReferenceToXml($registerGroupReference, $document)); $element->append($this->registerGroupInstanceToXml($registerGroupInstance, $document));
} }
if (!empty($peripheral->signals)) { if (!empty($peripheral->signals)) {
@@ -151,6 +152,25 @@ class ToXmlService
return $element; return $element;
} }
public function registerGroupInstanceToXml(
RegisterGroupInstance $registerGroupInstance,
DOMDocument $document
): DOMElement {
$element = $document->createElement('register-group-instance');
$element->setAttribute('key', $registerGroupInstance->key);
$element->setAttribute('name', $registerGroupInstance->name);
if (!empty($registerGroupInstance->description)) {
$element->setAttribute('description', $registerGroupInstance->description);
}
$element->setAttribute('register-group-key', $registerGroupInstance->registerGroupKey);
$element->setAttribute('address-space-key', $registerGroupInstance->addressSpaceKey);
$element->setAttribute('offset', $this->stringService->tryIntToHex($registerGroupInstance->offset));
return $element;
}
public function signalToXml(Signal $signal, DOMDocument $document): DOMElement public function signalToXml(Signal $signal, DOMDocument $document): DOMElement
{ {
$element = $document->createElement('signal'); $element = $document->createElement('signal');

View File

@@ -10,6 +10,7 @@ require_once __DIR__ . "/PropertyGroup.php";
require_once __DIR__ . "/AddressSpace.php"; require_once __DIR__ . "/AddressSpace.php";
require_once __DIR__ . "/PhysicalInterface.php"; require_once __DIR__ . "/PhysicalInterface.php";
require_once __DIR__ . "/Peripheral.php"; require_once __DIR__ . "/Peripheral.php";
require_once __DIR__ . "/RegisterGroupInstance.php";
require_once __DIR__ . "/Signal.php"; require_once __DIR__ . "/Signal.php";
require_once __DIR__ . "/Module.php"; require_once __DIR__ . "/Module.php";
require_once __DIR__ . "/RegisterGroup.php"; require_once __DIR__ . "/RegisterGroup.php";
@@ -246,6 +247,14 @@ class TargetDescriptionFile
: null; : null;
} }
public function resolveRegisterGroupInstance(
RegisterGroupInstance $registerGroupInstance,
string $moduleKey
): ?RegisterGroup {
$module = $this->getModule($moduleKey);
return $module instanceof Module ? $module->getRegisterGroup($registerGroupInstance->registerGroupKey) : null;
}
public function resolveRegisterGroupReference( public function resolveRegisterGroupReference(
RegisterGroupReference $registerGroupReference, RegisterGroupReference $registerGroupReference,
string $moduleKey string $moduleKey
@@ -258,12 +267,12 @@ class TargetDescriptionFile
{ {
$output = new TargetPeripheral($peripheral->name, []); $output = new TargetPeripheral($peripheral->name, []);
foreach ($peripheral->registerGroupReferences as $registerGroupReference) { foreach ($peripheral->registerGroupInstances as $registerGroupInstance) {
$registerGroup = $this->resolveRegisterGroupReference($registerGroupReference, $peripheral->moduleKey); $registerGroup = $this->resolveRegisterGroupInstance($registerGroupInstance, $peripheral->moduleKey);
if ($registerGroup instanceof RegisterGroup) { if ($registerGroup instanceof RegisterGroup) {
$output->registerGroups[] = $this->targetRegisterGroupFromRegisterGroup( $output->registerGroups[] = $this->targetRegisterGroupFromRegisterGroup(
$registerGroup, $registerGroup,
$registerGroupReference->offset ?? 0, $registerGroupInstance->offset ?? 0,
$peripheral->moduleKey $peripheral->moduleKey
); );
} }