News:

  • February 01, 2023, 10:22:08 AM

Login with username, password and session length

Author Topic: MEMCLEAR issues?  (Read 230 times)

TL140

  • Newbie
  • *
  • Posts: 3
MEMCLEAR issues?
« on: November 28, 2022, 12:15:52 AM »
Hello all.

Currently working on getting an advantech WOP-204k connected to a BRX.

I?m communicating through Modbus and would like to display a string. I?m currently doing this by doing a MEMCOPY on stStateMachine.sStepDesc - MHR100. The first string shows up fine. When my state transitions, I do a string clear and upon entry, I?m doing a string print in the step description variable. Everything works great. To update the HMI, I have a branch that?s doing a memory clear and under I have my mem copy. My MHR memory only seems to be overwritten when doing this, as I end up having remnants of the previous string in the memory block.

Am I using the block incorrectly?

Thanks

Bolt

  • Hero Member
  • *****
  • Posts: 492
Re: MEMCLEAR issues?
« Reply #1 on: November 28, 2022, 12:24:37 AM »
Are you doing an MEMCLEAR on your MHR data block?

TL140

  • Newbie
  • *
  • Posts: 3
Re: MEMCLEAR issues?
« Reply #2 on: November 28, 2022, 08:40:18 AM »
Are you doing an MEMCLEAR on your MHR data block?

That is correct.

I am attaching a photo below.


franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3463
    • Host Engineering
Re: MEMCLEAR issues?
« Reply #3 on: November 28, 2022, 10:07:23 AM »
Only the area used by the actual text length is set - the unused buffer characters are NOT set to spaces or NUL char.  For example, SS0 has a .MaxLength of 64.  If you set it to 64 characters of A's, the .Length will be 64 (along with .MaxLen) and the entire character area will contain the letter "A".  If you then set it to 1 character of "B", the first character will be "B", the .Length will be set to 1 (from 64) and .MaxLen will remain 64.  However, the remaining 63 bytes in the SS0 memory will still be "A"s.  This saves the PLC precious scan time to never clear memory you (typically) never see.  MEMCOPY from a STRING to Numeric data buffer will reveal this.

It is dangerous to use MEMCOPY with STRINGs - make sure BOTH SIDEs UNDERSTAND what is contained.  The first 2 WORDs are the .MaxLen and .Length members, followed by the text (i.e. .MaxLength number of characters).  STRGETB and STRPUTB are "safer" instructions.  Not sure what the Master is reading from MHR memory, but it needs to understand that memory layout of a Do-more string.

If you describe what the Master is trying to do, we can help with a good mechanism using STRGETB over MEMCOPY.

Oh, make sure you handle odd text lengths in your Master - is the odd byte in the HIBYTE or the LOBYTE of the Modbus Holding Register?  Do you need to pad it with a NUL character? a SPACE character?  Ah, Modbus and text.

Bolt

  • Hero Member
  • *****
  • Posts: 492
Re: MEMCLEAR issues?
« Reply #4 on: November 28, 2022, 10:19:43 AM »
One thing that gets me sometimes with STRPUTB is the null/whitespace character, $00, need to do a STRTRIM instruction on it after STRPUTB to clean up extra "noise".

TL140

  • Newbie
  • *
  • Posts: 3
Re: MEMCLEAR issues?
« Reply #5 on: November 28, 2022, 10:44:40 AM »
Only the area used by the actual text length is set - the unused buffer characters are NOT set to spaces or NUL char.  For example, SS0 has a .MaxLength of 64.  If you set it to 64 characters of A's, the .Length will be 64 (along with .MaxLen) and the entire character area will contain the letter "A".  If you then set it to 1 character of "B", the first character will be "B", the .Length will be set to 1 (from 64) and .MaxLen will remain 64.  However, the remaining 63 bytes in the SS0 memory will still be "A"s.  This saves the PLC precious scan time to never clear memory you (typically) never see.  MEMCOPY from a STRING to Numeric data buffer will reveal this.

It is dangerous to use MEMCOPY with STRINGs - make sure BOTH SIDEs UNDERSTAND what is contained.  The first 2 WORDs are the .MaxLen and .Length members, followed by the text (i.e. .MaxLength number of characters).  STRGETB and STRPUTB are "safer" instructions.  Not sure what the Master is reading from MHR memory, but it needs to understand that memory layout of a Do-more string.

If you describe what the Master is trying to do, we can help with a good mechanism using STRGETB over MEMCOPY.

Oh, make sure you handle odd text lengths in your Master - is the odd byte in the HIBYTE or the LOBYTE of the Modbus Holding Register?  Do you need to pad it with a NUL character? a SPACE character?  Ah, Modbus and text.

I actually was not aware of the string instructions STRGETB and STRPUTB, so I will attempt to use those.

When displaying the string on the HMI, it works well. It is only when I change the string that the leftovers show. Now, to note, I do have to offset to read the registers in the HMI to 40102, but the string shows up correctly so I know endianness is okay.

The HMI has the option for null-terminated and non-null terminated. The text only shows when the box is unchecked, just as expected since Do-More strings are not null terminated.

When I get to the house today I will take a look at the new (to me) instructions, but out of curiosity, that still does not answer why the MEMCLEAR command is not clearing it out, and I am wondering why?

EDIT: I now understand why it isn't clearing as stated by how the string is overwritten. I haven't had my coffee yet so forgive me
« Last Edit: November 28, 2022, 11:27:28 AM by TL140 »

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3463
    • Host Engineering
Re: MEMCLEAR issues?
« Reply #6 on: November 28, 2022, 12:58:31 PM »
Just to help clarify

MyString is a heap item with max length of 1024.

STRPRINT MyString Fill(0x31,1024)
That instruction moves the characters from the script into MyString, and sets MyString .Length to that generated script resulting length.  In this specific situation, the script ends up being 1024 of the character "1" (0x31 is numeric equivalent of ASCII "1"), so the entire character buffer of MyString is filled with "1"s and .Length member gets set to 1024.

Then this gets executed
STRPRINT MyString "A"

Here, the script result is a single character "A", so the first character in MyString's buffer gets set to "A" and .Length gets set to 1 (.Length was 1024 from previous STRPRINT).  The other 1023 characters in MyString buffer are not touched.  Since .Length is 1, the contents of MyString starting at char 2 through char 1024 does not matter, although they will still contain the character "1" or 0x31 from the previous STRPRINT.

I wrote a Sim program to show this, copying the contents of MyString to N block (not MHR) (see MEMCOPY1_String.png).  Leading Edge X0 fills MyString with "1" (0x31) and Leading Edge X1 sets MyString to the single letter "A" (0x41 BTW).

I show a couple screen shots of the contents of N0 through N513 (a copy of MyString structure memory) in HEXADECIMAL format in a Memory View
1. after X0 (MEMCOPY2_String.png)
2. after X1 (MEMCOPY3_String.png)

Note the values for N0 and N1 (WORDs of .MaxLength and .Length MyString struct fields in HEXADECIMAL), along with the value of the "text" in N2.

In the last screen shot, see how the contents of the MSBYTE of N3 through N513 are UNCHANGED (0x31) after turning X1 ON.  .MaxLength is still 1024 (N0 is 0x400) but the .Length is 1 (N1 is 0x0001).  N2, just the LSBYTE is changed (to 0x41 or "A", Little Endian, but N2's MSByte is still 0x31)