Freemaster witch packed struct pointers

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Freemaster witch packed struct pointers

Jump to solution
4,637 Views
Davidino
Contributor IV

Hello everyone,

I have used freemaster succesfully so far, but now I have a problem with a PACKED struct pointers. Freemaster shown values are not correct.

The struct is the following where MinasOutput*  and MinasInput* are two pointers to PACKED structs:

 

typedef struct
{
uint16 slaveNum; /*<! Numero dello slave del motore. */
MBDLT25BF_STATE state; /*<! Stato attuale del motore. */
MinasOutput* mbdlt25bfOut; /*<! Puntatore alla struct dei RxPDO. */
MinasInput* mbdlt25bfIn; /*<! Puntatore alla struct dei TxPDO. */
osal_timert tself; /*<! Timer utilizzato per controllare la buona riuscita di un'operazione. */

int acc, dec, max, duration;
DIRECTION direction;
int counter;
}tMbdlt25bf;

 

On freemaster_cfg.c I did:

 

FMSTR_TSA_RO_VAR(mbdlt25bf, FMSTR_TSA_USERTYPE(tMbdlt25bf))

FMSTR_TSA_STRUCT(tMbdlt25bf)
FMSTR_TSA_MEMBER(tMbdlt25bf, state, FMSTR_TSA_USERTYPE(MBDLT25BF_STATE))
FMSTR_TSA_MEMBER(tMbdlt25bf, acc, FMSTR_TSA_SINT32)
FMSTR_TSA_MEMBER(tMbdlt25bf, dec, FMSTR_TSA_SINT32)
FMSTR_TSA_MEMBER(tMbdlt25bf, duration, FMSTR_TSA_SINT32)
FMSTR_TSA_MEMBER(tMbdlt25bf, max, FMSTR_TSA_SINT32)
FMSTR_TSA_MEMBER(tMbdlt25bf, counter, FMSTR_TSA_SINT32)
FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfOut, FMSTR_TSA_USERTYPE(MinasOutput))
FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfIn, FMSTR_TSA_USERTYPE(MinasInput))

FMSTR_TSA_STRUCT(MinasOutput)
FMSTR_TSA_MEMBER(MinasOutput, controlword, FMSTR_TSA_UINT16)
FMSTR_TSA_MEMBER(MinasOutput, operation_mode, FMSTR_TSA_SINT8)
FMSTR_TSA_MEMBER(MinasOutput, target_torque, FMSTR_TSA_SINT16)
FMSTR_TSA_MEMBER(MinasOutput, max_torque, FMSTR_TSA_UINT16)
FMSTR_TSA_MEMBER(MinasOutput, target_position, FMSTR_TSA_SINT32)
FMSTR_TSA_MEMBER(MinasOutput, max_motor_speed, FMSTR_TSA_UINT32)
FMSTR_TSA_MEMBER(MinasOutput, touch_probe_function, FMSTR_TSA_UINT16)
FMSTR_TSA_MEMBER(MinasOutput, target_velocity, FMSTR_TSA_SINT32)
FMSTR_TSA_MEMBER(MinasOutput, position_offset, FMSTR_TSA_SINT32)

 

Is there an alternative solution instead of coping struct field values to some variables and share the latters with freemaster tool ?

Thank you.

Regards,

Davidino

0 Kudos
Reply
1 Solution
4,445 Views
MichalH
NXP Apps Support
NXP Apps Support

Hello Davidino,

with TSA, the FreeMASTER driver in the MCU actively monitors any access and it denies reading or writing to a memory which is not "described" by at least one TSA entry. It also protects a write access to memory locations marked in TSA as RO (Read-only).

You can turn this protection off (set FMSTR_USE_TSA_SAFETY to 0). This will keep the TSA basic functionality, but will disable the memory access checks.

I think this is the reason for the question mark. If not, let me know and we will investigate further.

Regards,
Michal

 

View solution in original post

12 Replies
4,621 Views
MichalH
NXP Apps Support
NXP Apps Support

Dear Davidino,

the problem is not is the packed structures, but in the fact that you only have pointers to them. You should treat this type as FMSTR_TSA_POINTER which is in fact just a 32bit number. 

If you indeed need to read/write the structure members, it would be best to include them directly into the top level structure (not via pointers) or at least give them a fixed (static/global) addresses and access them individually.

There is also a solution for you to access the two child structures indirectly and without a fixed pointers, but this is more complex and will require some small JavaScript support. Let me know if this is needed, I can guide you through necessary steps.

Regards,
Michal

0 Kudos
Reply
4,615 Views
Davidino
Contributor IV

Hello @MichalH ,

thank you very much for your answer. Among the several solution that you proposed me I'd go with the simpler (the one using FMSTR_TSA_POINTER I think) as I don't need to write the fields, only reading is requested.

I cannot make them as structs, as the struct memory locations are shared through an union to an array; and I cannot change that part.

CAn you provide me an example about the simpler approach?

Thank you.

Davidino

0 Kudos
Reply
4,612 Views
MichalH
NXP Apps Support
NXP Apps Support

Hello,

the simpler way without JavaScript involved:

  1. In TSA table, have the mbdlt25bfOut member defined as FMSTR_TSA_POINTER
  2. In FreeMASTER, create a variable (4-byte unsigned) to read this member "mbdlt25bf.mbdlt25bfOut"
  3. You can put this variable to a Watch to make sure the variable is readable. The value of the variable should be an address of the referenced structure in memory.
  4. Note that you should never change the pointer in your application. It should be constant value.
  5. You can set sampling period of this variable to "once"

Now you can access e.g. the "mbdlt25bf.mbdlt25bfOut->controlword" member:

  1. Define a new variable with this address: valueof(mbdlt25bf.mbdlt25bfOut) + offsetof(MinasOutput, controlword)
  2. You need to set the size manually to 2 bytes (controlword is uint16).
  3. Note that when FreeMASTER reads the variable, it first reads the "mbdlt25bf.mbdlt25bfOut", then it evaluates the value (valueof() operator) and uses it to calculate an address of the controlword member.

 

 

Harder, but more effective way with JavaScript. JavaScript is able to programmatically retrieve an address of the mbdlt25bf.mbdlt25bfOut pointer and define a new symbol properly typed as a pointer to MinasOutput. The members of the referenced structure than appear automatically in the FreeMASTER symbols list:

<!DOCTYPE html>
<html>
<head>
</head>
<body onload="main()">

<OBJECT id="pcm" height="0" width="0" classid="clsid:48A185F1-FFDB-11D3-80E3-00C04F176153">
</OBJECT>

<script>
function main()
{
if(pcm.ReadUIntVariable("mbdlt25bf.mbdlt25bfOut", 4))
{
if(pcm.DefineSymbol("mbdlt25bf.mbdlt25bfOut_ptr", pcm.LastVariable_vValue, "MinasOutput*", 4))
console.log("mbdlt25bf.mbdlt25bfOut_ptr symbol defined at address" + pcm.LastVariable_vValue);
else
console.log("Error defining the mbdlt25bf.mbdlt25bfOut_ptr");
}
else
{
console.log("Error reading mbdlt25bf.mbdlt25bfOut");
}
}
</script>
</body>
</html>

 

0 Kudos
Reply
4,591 Views
Davidino
Contributor IV

Hello @MichalH ,

thank you for your answer. I searched for some piece of code that uses FMSTR_TSA_POINTER but it doesn't exist, neither in SDK Freemaster example nor in documentation. How do I substitute

FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfOut, FMSTR_TSA_USERTYPE(MinasOutput))
FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfIn, FMSTR_TSA_USERTYPE(MinasInput))

with FMSTR_TSA_POINTER considering that its definition is

"extern FMSTR_TSA_CDECL char FMSTR_TSA_POINTER[]"?

Thank you.

Regards,

Davidino

0 Kudos
Reply
4,586 Views
MichalH
NXP Apps Support
NXP Apps Support

Hello,

it should be a simply:

FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfOut, FMSTR_TSA_POINTER)
FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfIn, FMSTR_TSA_POINTER)

 

or you could also replace it with just FMSTR_TSA_UINT32 as the pointer is 4 bytes long and our intent is just to read the pointer value.

Regards,
Michal

4,583 Views
Davidino
Contributor IV

Hello @MichalH ,

thank you for your message. I did as you showed me and FMSTR_TSA_POINTER is ok.
Now I have a problem with:

valueof(mbdlt25bf.mbdlt25bfOut) + offsetof(MinasOutput, controlword)

I didn't find any info about that on internet except that it's a new feature of Freemaster version 3.1.4. I can't find out how to implement it. Besides searching for the functions offsetof and valueof in the code, I couldn't find them.


Could you explain me?

Thank you for your cooperation.

Davidino

0 Kudos
Reply
4,573 Views
MichalH
NXP Apps Support
NXP Apps Support

Hello,

both valueof and offsetof operators can be used when defining a FreeMASTER variable object. Each FreeMASTER variable needs to know the address (in target MCU memory space) from where the FreeMASTER could read the required value. Normally, you specify either a direct numeric address or you can use a C-language symbol obtained by reading application’s ELF file. In more advanced way, the TSA-defined symbols can be used – but in any case, such symbol resolves to a single constant numeric address.

In your case, the address of the mbdlt25bf.mbdlt25bfOut->controlword is not statically available in ELF file nor in the TSA because the mbdlt25bfOut is a pointer whose value can be dynamically changed in the application. This is why you need to define the address using the expression:

valueof(mbdlt25bf.mbdlt25bfOut) + offsetof(MinasOutput, controlword)

The valueof operator reads a value of the given FreeMASTER variable (which must exist in FreeMASTER project, it can be sampled “once” as we assume the pointer will not change).

The offsetof operator returns an offset of a given member withing a structure type.

All together, this expression returns an address of mbdlt25bf.mbdlt25bfOut->controlword.

 

In FreeMASTER, there is a hint describing the operators:

MichalH_1-1658434012273.png

 

Regards,
Michal

4,566 Views
Davidino
Contributor IV

Hello @MichalH,

thank you for your patience and support. I installed the new freemaster version 3.2 so that it's possible to define expression for the variable addresses. My freemaster_cfg.c now looks like this:

 

	FMSTR_TSA_STRUCT(tMbdlt25bf)
	FMSTR_TSA_MEMBER(tMbdlt25bf, state, FMSTR_TSA_USERTYPE(MBDLT25BF_STATE))
	FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfOut, FMSTR_TSA_POINTER)
	FMSTR_TSA_MEMBER(tMbdlt25bf, mbdlt25bfIn, FMSTR_TSA_POINTER)

	FMSTR_TSA_STRUCT(MinasOutput)
	FMSTR_TSA_MEMBER(MinasOutput, controlword, FMSTR_TSA_UINT16)
	FMSTR_TSA_MEMBER(MinasOutput, operation_mode, FMSTR_TSA_SINT8)
	FMSTR_TSA_MEMBER(MinasOutput, target_torque, FMSTR_TSA_SINT16)
	FMSTR_TSA_MEMBER(MinasOutput, max_torque, FMSTR_TSA_UINT16)
	FMSTR_TSA_MEMBER(MinasOutput, target_position, FMSTR_TSA_SINT32)
	FMSTR_TSA_MEMBER(MinasOutput, max_motor_speed, FMSTR_TSA_UINT32)
	FMSTR_TSA_MEMBER(MinasOutput, touch_probe_function, FMSTR_TSA_UINT16)
	FMSTR_TSA_MEMBER(MinasOutput, target_velocity, FMSTR_TSA_SINT32)
	FMSTR_TSA_MEMBER(MinasOutput, position_offset, FMSTR_TSA_SINT32)

	FMSTR_TSA_STRUCT(MinasInput)
	FMSTR_TSA_MEMBER(MinasInput, error_code, FMSTR_TSA_UINT16)
	FMSTR_TSA_MEMBER(MinasInput, statusword, FMSTR_TSA_UINT16)
	FMSTR_TSA_MEMBER(MinasInput, operation_mode, FMSTR_TSA_USERTYPE(PDS_OPERATION))
	FMSTR_TSA_MEMBER(MinasInput, position_actual_value, FMSTR_TSA_SINT32)
	FMSTR_TSA_MEMBER(MinasInput, velocity_actual_value, FMSTR_TSA_SINT32)
	FMSTR_TSA_MEMBER(MinasInput, torque_actual_value, FMSTR_TSA_SINT16)
	FMSTR_TSA_MEMBER(MinasInput, touch_probe_status, FMSTR_TSA_UINT16)
	FMSTR_TSA_MEMBER(MinasInput, touch_probe_posl_pos_value, FMSTR_TSA_SINT32)
	FMSTR_TSA_MEMBER(MinasInput, digital_inputs, FMSTR_TSA_UINT32)

 

One thing that I didn't tell you is that my mbdlt25bf struct is actually an array of struct:

 

tMbdlt25bf mbdlt25bf[ARRAY_SIZE_MOTORS];

 

I've one more issue where I'm trying to get the value stored in the variable mbdlt25bf[7].mbdlt25bfOut->controlWord.

The address that I wrote is: valueof(mbdlt25bf[7].mbdlt25bfOut) + offsetof(MinasOutput, controlword), as shown in the picture.

Davidino_1-1658478758280.png

As you can see the value doesn't get updated. Can you advise me?

Thank you again for your cooperation.

Davidino

 

0 Kudos
Reply
4,552 Views
MichalH
NXP Apps Support
NXP Apps Support

Hello,

you should first make sure that the FreeMASTER determines the address of mbdlt25bf[7].mbdlt25bfOut member correctly. One way of verifying that would be to examine this member in a debugger or print it to console by the MCU application. In any case, the address of this element should match what FreeMASTER prints in the Variable definition dialog (in my example it prints an address of variable named "var16").

MichalH_0-1658495620255.png

If mbdlt25bf is really an array, the FreeMASTER should understand it and calculate a correct address. Basically, to access the mbdlt25bf[7].mbdlt25bfOut member, the FreeMASTER calculates something like:

mbdlt25bf + 7*sizeof(tMbdlt25bf) + offsetof(tMbdlt25bf, mbdlt25bfOut)

This is a fixed address (not runtime) so FreeMASTER should be able to show it to you in the Variable definition dialog. You should be able to see the address just like I see it for my "var16" above.

 

When you are sure the above is correct, define a FreeMASTER variable named mbdlt25bf[7].mbdlt25bfOut with the same address specification and size=4 bytes. You should be able to put this variable into a Watch and see the value of the mbdlt25bfOut pointer.

Last, you will be able to define a new FreeMASTER variable named mbdlt25bf[7].mbdlt25bfOut->controlword  with address defined by the runtime expression as we discussed earlier:

valueof(mbdlt25bf[7].mbdlt25bfOut) + offsetof(MinasOutput, controlword)

This address is calculated in run-time, because FreeMASTER must first read the mbdlt25bf[7].mbdlt25bfOut variable and add the fixed controlword member offset to the obtained value. 

_____________________________

As you can see, dealing with pointers in FreeMASTER is tricky. I would advise again not to declare the mbdlt25bfOut member as a pointer to a MinasOutput structure, but to include the full structure directly. This will enable FreeMASTER to calculate address of mbdlt25bf[7].mbdlt25bfOut.controlword statically and access the controlword member directly.

 

Regards,
Michal

0 Kudos
Reply
4,462 Views
Davidino
Contributor IV

Hello @MichalH ,

thanks for your detailed answer. I can confirm you that the address stored in mbdlt25bf[7].mbdlt25bfOut is correct (green box in the picture) as it is confirmed in MCUXpresso with the debugger. However, the address valueof(mbdlt25bf[7].mbdlt25bfOut) isn't computed correctly as it shows the question mark (red box in the picture). I don't understand why this happens.

Nuova immagine bitmap.bmp

P.S. In case this method doesn't work, I'll create copy of mbdlt25bfOut and mbdlt25bfIn structs and ciclically update the values for the solely purpose of seeing them on Freemaster.
Giving up on struct pointers would affect my program performances.

Thank you again.

Davidino

0 Kudos
Reply
4,446 Views
MichalH
NXP Apps Support
NXP Apps Support

Hello Davidino,

with TSA, the FreeMASTER driver in the MCU actively monitors any access and it denies reading or writing to a memory which is not "described" by at least one TSA entry. It also protects a write access to memory locations marked in TSA as RO (Read-only).

You can turn this protection off (set FMSTR_USE_TSA_SAFETY to 0). This will keep the TSA basic functionality, but will disable the memory access checks.

I think this is the reason for the question mark. If not, let me know and we will investigate further.

Regards,
Michal

 

4,440 Views
Davidino
Contributor IV

Hello @MichalH ,

Thank you very much for your support and patience!

That was the solution.

0 Kudos
Reply