thelsing / knx

knx stack (TP, IP and RF) for arduino and linux, Can be configured with ETS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect Parameter Encoding (int32)

rueckix opened this issue · comments

Trying to configure and read a 32bit int parameter, I am observing that they are not encoded (by ETS 5) as expected and therefore cannot be recovered by this knx stack.

XML Parameter Type

              <ParameterType Id="M-00FA_A-EA61-7B-0000_PT-BlindRuntime" Name="BlindRuntime">
                <TypeNumber SizeInBit="32" Type="unsignedInt" minInclusive="0" maxInclusive="600" />

XML Parameters

            <Parameters>
              <Parameter Id="M-00FA_A-EA61-7B-0000_P-1" Name="tBlind1" ParameterType="M-00FA_A-EA61-7B-0000_PT-BlindRuntime" Text="Rolladen 1 Laufzeit [s]" Value="30">
                <Memory CodeSegment="M-00FA_A-EA61-7B-0000_RS-04-00000" Offset="0" BitOffset="0" />
              </Parameter>
              <Parameter Id="M-00FA_A-EA61-7B-0000_P-2" Name="tBlind2" ParameterType="M-00FA_A-EA61-7B-0000_PT-BlindRuntime" Text="Rolladen 2 Laufzeit [s]" Value="30">
                <Memory CodeSegment="M-00FA_A-EA61-7B-0000_RS-04-00000" Offset="4" BitOffset="0" />
              </Parameter>
            </Parameters>

XML Load Procedure

<LoadProcedures>
              <LoadProcedure MergeId="2">
                <LdCtrlRelSegment LsmIdx="4" Size="8" Mode="0" Fill="0" AppliesTo="full" />
              </LoadProcedure>
              <LoadProcedure MergeId="4">
                <LdCtrlWriteRelMem ObjIdx="4" Offset="0" Size="8" Verify="true" />
              </LoadProcedure>
</LoadProcedures>

Resulting Encoding

Output of printHex("", knx.paramData(0), 50);

  1. Value 300 for both parameters
    00 20 01 2C 00 00 01 2C | 00 0F 13 00 13 00 53 00 4B 07 13 00 13 00 53 00 4B 07 13 00 13 00 5B 00 13 00 13 00 5B 00 5B 00 00 00 FF FF 00 00 FF FF FF FF

  2. Value 10 for both parameters
    00 20 00 0A 00 00 00 0A | 00 0F 13 00 13 00 53 00 4B 07 13 00 13 00 53 00 4B 07 13 00 13 00 5B 00 13 00 13 00 5B 00 5B 00 00 00 FF FF 00 00 FF FF FF FF

Hypothesis 1

  • 00 20 (hex) encodes 32 (dec), which I assume is indicating that a 32 bit value follows. The knx stack, however, interprets this as part of param(0)
  • 01 2C (example 1) and 00 0A (example 2) encode 300 and 10 respectively. However, 2 byte are used - not 4 as expected.
  • The second parameter is again encoded in 2 byte at offset 4 (4 byte after the leading 00 20). Hence, leaving two byte "00 00" in between.
  • Hence, we should assume 16 bit and adjust the offsets accordingly

Hypothesis 2

  • ETS correctly writes 4 byte per parameter "00 00 01 2C" and "00 00 00 0A" respectively
  • ETS overwrites the first 2 byte with the length "00 20" of the parameter
  • Hence, we should ask ETS to offset the first parameter by 2 byte

I am somehow leaning towards Hypothesis 2, but I am not an export on how ETS is supposed to work. Can anybody shed some light on this before we go down either of these rabbit holes.

Unfortunately I have not idea where this comes from. Maybe you can find some information in the help file of the knx manufacturers tool.

@thelsing, are you referring to https://support.knx.org/hc/en-us/sections/360003163640-User-Guide or to anything that would be restricted to KNX members?

No if you download MT from my.knx.org you can install it. (But not use it, unless you have a license on a dongle.)
In the install directory you can find a Windows-Help file.

But first I would check what ETS actually sends to the device.
It unloads the interface objects, Then for each obj: allocate memory; write memory.

The object index is translated here:

InterfaceObject* Bau07B0::getInterfaceObject(uint8_t idx)

(for TP-Devices)
Parameters go to the ApplicationProgramObject so index 4.

Thanks and indeed... ETS and programming does not appear to be the problem here. looked into what it stored in EEPROM (emulated) at the various stages of programming and notices that there is an issue with _metadataSize, causing the parameters to overlap with the metadata region.

Here's where I think the issue is.

writeMemory has two unconditional pushWord calls. So 4 byte. I don't think they are accounted for. Initializing _medataDataSize=4 shifts the remaining segments further to the right, so that params are not affected any longer.

Does that look reasonable (before I work on a PR)?

I think you are right. The pushByteArray call for HARDWARE_TYPE should probably also added to _metadatasize. Please also add some comments where the initialized number comes from.

Need to look into that some more. I find a bit suspicious that this leads to a bunch of 0xFF at the end. Not harmful but wasteful.

The counts look ok, but why would those bytes not be overwritten if that space is really needed?