export_pev2_pins(prefix, comp_id, device):
pev2 ← hal_malloc(sizeof(sPoKeysHalPEv2))
if pev2 == NULL: return -ENOMEM
/* Export global output pins */
hal_pin_u32_newf(HAL_OUT, &pev2->pin_nrOfAxes, comp_id, "%s.PEv2.nrOfAxes", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_maxPulseFrequency,comp_id, "%s.PEv2.maxPulseFrequency", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_bufferDepth, comp_id, "%s.PEv2.bufferDepth", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_slotTiming, comp_id, "%s.PEv2.slotTiming", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_PulseEngineEnabled, comp_id, "%s.PEv2.PulseEngineEnabled", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_PulseGeneratorType, comp_id, "%s.PEv2.PulseGeneratorType", prefix)
hal_pin_bit_newf(HAL_OUT, &pev2->pin_PG_swap_stepdir, comp_id, "%s.PEv2.PG_swap_stepdir", prefix)
hal_pin_bit_newf(HAL_OUT, &pev2->pin_PG_extended_io, comp_id, "%s.PEv2.PG_extended_io", prefix)
hal_pin_bit_newf(HAL_OUT, &pev2->pin_ChargePumpEnabled, comp_id, "%s.PEv2.ChargePumpEnabled", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_PulseEngineActivated, comp_id, "%s.PEv2.PulseEngineActivated", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_PulseEngineState, comp_id, "%s.PEv2.PulseEngineState", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_MiscInputStatus, comp_id, "%s.PEv2.MiscInputStatus", prefix)
for i in 0..7:
hal_pin_bit_newf(HAL_OUT, &pev2->pin_digin_Misc_in[i], comp_id, "%s.PEv2.digin.Misc-%d.in", prefix, i)
hal_pin_bit_newf(HAL_OUT, &pev2->pin_digin_Misc_in_not[i], comp_id, "%s.PEv2.digin.Misc-%d.in-not", prefix, i)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_LimitOverride, comp_id, "%s.PEv2.LimitOverride", prefix)
hal_pin_bit_newf(HAL_OUT, &pev2->pin_digin_Emergency_in, comp_id, "%s.PEv2.digin.Emergency.in", prefix)
hal_pin_bit_newf(HAL_OUT, &pev2->pin_digin_Emergency_in_not, comp_id, "%s.PEv2.digin.Emergency.in-not", prefix)
hal_pin_bit_newf(HAL_OUT, &pev2->pin_digin_Probed_in, comp_id, "%s.PEv2.digin.Probed.in", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_AxisEnabledMask, comp_id, "%s.PEv2.AxisEnabledMask", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_AxisEnabledStatesMask, comp_id, "%s.PEv2.AxisEnabledStatesMask", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_ExternalRelayOutputs, comp_id, "%s.PEv2.ExternalRelayOutputs", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_ExternalOCOutputs, comp_id, "%s.PEv2.ExternalOCOutputs", prefix)
for i in 0..3:
hal_pin_bit_newf(HAL_IN, &pev2->pin_digout_ExternalRelay_out[i], comp_id, "%s.PEv2.digout.ExternalRelay-%d.out", prefix, i)
hal_pin_bit_newf(HAL_IN, &pev2->pin_digout_ExternalOC_out[i], comp_id, "%s.PEv2.digout.ExternalOC-%d.out", prefix, i)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_ProbeStatus, comp_id, "%s.PEv2.ProbeStatus", prefix)
hal_pin_u32_newf(HAL_OUT, &pev2->pin_BacklashCompensationEnabled, comp_id, "%s.PEv2.BacklashCompensationEnabled", prefix)
/* Export global input pins */
hal_pin_bit_newf(HAL_IN, &pev2->pin_digout_Emergency_out, comp_id, "%s.PEv2.digout.Emergency.out", prefix)
hal_pin_u32_newf(HAL_IN, &pev2->pin_LimitOverrideSetup, comp_id, "%s.PEv2.LimitOverrideSetup", prefix)
hal_pin_u32_newf(HAL_IN, &pev2->pin_HomingStartMaskSetup, comp_id, "%s.PEv2.HomingStartMaskSetup", prefix)
hal_pin_u32_newf(HAL_IN, &pev2->pin_ProbeStartMaskSetup, comp_id, "%s.PEv2.ProbeStartMaskSetup", prefix)
hal_pin_float_newf(HAL_IN, &pev2->pin_ProbeSpeed, comp_id, "%s.PEv2.ProbeSpeed", prefix)
/* Export global parameters */
hal_param_u32_newf(HAL_RW, &pev2->param_digin_Emergency_Pin, comp_id, "%s.PEv2.digin.Emergency.Pin", prefix)
hal_param_bit_newf(HAL_RW, &pev2->param_digin_Emergency_invert, comp_id, "%s.PEv2.digin.Emergency.invert", prefix)
hal_param_u32_newf(HAL_RW, &pev2->param_digout_Emergency_Pin, comp_id, "%s.PEv2.digout.Emergency.Pin", prefix)
hal_param_u32_newf(HAL_RW, &pev2->param_digin_Probe_Pin, comp_id, "%s.PEv2.digin.Probe.Pin", prefix)
hal_param_bit_newf(HAL_RW, &pev2->param_digin_Probe_invert, comp_id, "%s.PEv2.digin.Probe.invert", prefix)
/* Determine axis count */
n_axes ← device->PEv2.info.nrOfAxes
if n_axes == 0:
rtapi_print_msg(RTAPI_MSG_WARN, "PEv2: nrOfAxes=0, defaulting to 8")
n_axes ← 8
/* Export per-axis pins and parameters */
for ax in 0..(n_axes-1):
export_pev2_axis_pins(pev2, comp_id, prefix, ax)
device->PEv2.pHal = pev2
return 0
[RT Servo Thread — 1 kHz]
|
|-- pev2_write_hal_to_device(pev2, dev) [HAL inputs → device struct]
|
|-- PK_PEv2_ExternalOutputsSetAsync(dev) [send relay/OC outputs]
|-- PK_PEv2_PulseEngineMovePVAsync(dev) [send motion command if active]
|
|-- PK_PEv2_StatusGetAsync(dev) [request status (async, no block)]
|
|-- [Later: receive parsed by PK_PEv2_StatusParse callback]
|
|-- pev2_read_device_to_hal(pev2, dev) [device struct → HAL outputs]
|
|<-- return
Software Design Description (IEEE 1016-2009)
Architecture Component: #132 (ARC-C-PEV2: PulseEngine v2 HAL Interface)
Architecture Decisions: #127, #128, #129, #130, #131
Requirements: #116, #117, #118, #119, #120, #121,
#122, #123, #124
1. Logical Design View
1.1 Data Types (
PoKeysLibHal.h)sPoKeysHalPEv2Axis(per-axis HAL pin/param storage)Implements: #131 (per-axis sub-struct)
1.2 Static Storage (
PoKeysLibPulseEngine_v2Async.c)No dynamic allocation;
sPoKeysHalPEv2is allocated from HAL shared memory viahal_malloc()duringexport_pev2_pins().2. Algorithms
2.1
export_pev2_pins()— HAL Pin and Parameter ExportPrecondition:
comp_idis valid (returned byhal_init()),deviceis non-NULL.2.2
pev2_read_device_to_hal()— Device Status to HAL OutputsComplexity: O(nAxes), worst case O(8)
2.3
pev2_write_hal_to_device()— HAL Inputs to Device Struct3. Interaction View — Servo Cycle Sequence
4. Implementation View — File Mapping
PoKeysLibHal.hsPoKeysHalPEv2,sPoKeysHalPEv2Axisstruct definitionsPoKeysLibPulseEngine_v2Async.cexport_pev2_pins(),pev2_read_device_to_hal(),pev2_write_hal_to_device(), allPK_PEv2_*Async()functionsPoKeysLibAsync.hregister_async_task()declarationexperimental/pokeys_async.cexport_pev2_pins()inEXTRA_SETUP()5. Design Rationale
All design choices trace directly to the ADRs:
pokeys.[DevID].PEv2.*→ ADR-PEV2-001: HAL Pin Naming Convention for PEv2 Interface #127nrOfAxes→ ADR-PEV2-002: Axis-Conditional Pin Creation Based on nrOfAxes #128*-notpins → ADR-PEV2-003: Bitmapped-to-HAL-Pin Decomposition Strategy #129pev2_read_device_to_hal()/pev2_write_hal_to_device()functions → ADR-PEV2-004: Read/Write Phase Separation in PEv2 Servo Cycle #130sPoKeysHalPEv2/sPoKeysHalPEv2Axisstruct organisation → ADR-PEV2-005: sPoKeysHalPEv2 Global vs Per-Axis Struct Organisation #131Traceability
REQ-F-PEV2-007: HAL Parameter Export for Pin Assignments and Invert Flags #122, REQ-F-PEV2-008: PoKeysLib Async Function Call Sequence for PEv2 #123, REQ-NF-PEV2-001: Real-Time Safety - No Blocking Calls in PEv2 RT Path #124
PoKeysLibPulseEngine_v2Async.c,PoKeysLibHal.h