Reading and writing issues of Multi-dimentional array -FreeMASTER Lite

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

Reading and writing issues of Multi-dimentional array -FreeMASTER Lite

Jump to solution
1,868 Views
yono233
Contributor II

I attempted to read and write a multi-dimensional array using FreeMASTER Lite.

For example, in the following structure, the "pp_R" part.

```c

typedef struct
{
    float   pp_R[COMB_MAX_NUM][MATRIX_MAX_SIZE][MATRIX_MAX_SIZE];
    float   pp_LC[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE];
    float   YL[MATRIX_MAX_SIZE];
    float   YC[MATRIX_MAX_SIZE];
    float   YR[MATRIX_MAX_SIZE];
    uint8_t attr[MATRIX_MAX_SIZE];

    float   vhs[MATRIX_MAX_SIZE];
    float   J[MATRIX_MAX_SIZE];
} _SYSTEM_MATRIX;

````

I have tried TSA and ELF parsing.

In FreeMASTER, R&W operations can be performed normally, but in Lite, they cannot.

After testing, it seems that Lite only supports one-dimensional arrays. Is that true?

Tags (1)
0 Kudos
Reply
1 Solution
1,761 Views
iulian_stan
NXP Employee
NXP Employee

Thank you for details. I confirmed the issue on FreeMASTER Lite side - there is bug in expression evaluation (when it tries to convert the symbol to an address). It will be addressed it in the next release. 

Just to be clear - FreeMASTER nor FreeMASTER Lite cannot resolve multi dimensional arrays. That is why you could not use multiple indexes in the First scenario.

When you defined additional TSA Members such as:

FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][0], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][1], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][2], FMSTR_TSA_FLOAT)

each one is treated as separate symbol (not an actional multidimensional array). And FreeMASTER resolves SysMatrixRun.pp_R[0][1][k] address as SysMatrixRun.pp_R[0][1](symbol base address) + k(offset).

Usually, I would define variables using the first approach you described and compute the offset from matrix symbol:

addr: SysMatrixRun.pp_R[i][j][k] → SysMatrixRun.pp_R[i * d2 * d3 + j * d3 + k]

where d2, d3 are matrix dimension and can be computed either based on symbol size or using helper variables. The reason is that in order to emulate the access using independent indexes requires definitions of additional symbols (down to one dimensional arrays) which creates additional overhead if matrix dimensions change.

View solution in original post

0 Kudos
Reply
4 Replies
1,847 Views
iulian_stan
NXP Employee
NXP Employee

Hi @yono233,

Could you please elaborate on your tests ? What API calls did you use and which ones passed on FreeMASTER and failed on Lite ?

FreeMASTER Lite handles all symbols as continuous memory regions.  Let's assume that:

#define COMB_MAX_NUM 2
#define MATRIX_MAX_SIZE 4
_SYSTEM_MATRIX matrix = {};

After reading the TSA FreeMASTER Lite will create the following symbols:

=> pcm.GetSymbolInfo('matrix').then(console.log).catch(console.error)
<= {success: true, data: {addr: 536877192, size: 276, type: '_SYSTEM_MATRIX'}}
=> pcm.GetSymbolInfo('matrix.pp_R').then(console.log).catch(console.error)
<= {success: true, data: {addr: 536877192, size: 128, type: 'float'}}
=> pcm.GetSymbolInfo('matrix.pp_R[0]').then(console.log).catch(console.error)
<= {success: true, data: {addr: 536877192, size: 4, type: 'float'}}

To manipulate the pp_R array you would use matrix.pp_R symbol either via ReadFloatVariable, ReadFloatArray or WriteFloatVariable, WriteFloatArray.

If symbol name is used with a index: matrix.pp_R[i] the address to the memory area will be computed as i * 4 (float size) offset with respect to matrix.pp_R address.

0 Kudos
Reply
1,819 Views
yono233
Contributor II

Now, I calculate the actual address I need by reading the base addr and the offset addr, and calculate the address for each Symbol.

In this way, I can freely access each Symbol. This is a feasible solution, but I'm not sure if it is the best practice? 

I just want to R/W SysMatrixRun.pp_R[1][1][1]  as in the MCU.

data = await self._send_request('ReadTSA')

data_base = await self._send_request('GetSymbolInfo', "SysMatrixRun.pp_R[0][0][0]")
data = await self._send_request('GetSymbolInfo', "SysMatrixRun.pp_R[0][1][0]")
self.pp_R_base = data_base['addr']
self.MATRIX_MAX_SIZE = int((data['addr'] - data_base['addr']) / 4)

data_base = await self._send_request('GetSymbolInfo', "SysMatrixRun.pp_LC[0][0]")
self.pp_LC_base = data_base['addr']

self.COMB_MAX_NUM = int((self.pp_LC_base - self.pp_R_base)/(self.MATRIX_MAX_SIZE*self.MATRIX_MAX_SIZE*4))

# 注册pp_R
for i in range(self.COMB_MAX_NUM):
    for j in range(self.MATRIX_MAX_SIZE):
        for k in range(self.MATRIX_MAX_SIZE):
            addr = self.pp_R_base + ((i * self.MATRIX_MAX_SIZE * self.MATRIX_MAX_SIZE + j * self.MATRIX_MAX_SIZE + k) * 4)
            variable = {
                'name': f"SysMatrixRun.pp_R[{i}][{j}][{k}]",
                'addr': addr,
                'type': 'float',
                'size': 4
            }
            try:
                await self._send_request('DefineVariable', variable)
            except Exception as e:
                logging.warning(f"DefineVariable failed: {variable['name']} - {e}")

 

0 Kudos
Reply
1,833 Views
yono233
Contributor II

Thanks.

I will provide detailed tests.

 

#define COMB_MAX_NUM 260
#define MATRIX_MAX_SIZE 10

_SYSTEM_MATRIX SysMatrixRun= {};

 

Let's understand the two symbols: SysMatrixRun.vhs[5] and SysMatrixRun.pp_R[0][1][1]

 

The first

I use this method TSA

 

FMSTR_TSA_TABLE_BEGIN(first_table)
FMSTR_TSA_RW_VAR(SysMatrixRun, FMSTR_TSA_USERTYPE(_SYSTEM_MATRIX))
FMSTR_TSA_STRUCT(_SYSTEM_MATRIX)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, YL, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, YC, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, YR, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, attr, FMSTR_TSA_UINT8)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, vhs, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, J, FMSTR_TSA_FLOAT)
FMSTR_TSA_TABLE_END( )

FMSTR_TSA_TABLE_LIST_BEGIN( )
FMSTR_TSA_TABLE(first_table)
FMSTR_TSA_TABLE_LIST_END( )

 

 I can load TSA in MASTER or lite. Then I conducted a test using Python.

This will obtain TSA.

 

    data = await SendRequest(ws, 'ReadTSA')
    global count
    count = int(data['count'])
    print('Parsed TSA contained %d symbols.' % count)

    global variable
    for i in range(count):
        data = await SendRequest(ws, 'EnumSymbols', i)
        print(data)

 

Then, this will successfully read the actual value.. For example, >> 41.23

 

    variable = {
        'name': 'SysMatrixRun.vhs[5]',
        'addr': 'SysMatrixRun.vhs[5]',
        'type': 'float',
        'size': 4
    }
    await SendRequest(ws, 'DefineVariable', variable)
    data = await SendRequest(ws, 'ReadVariable', variable['name'])
    print(data)

 

But then,this will unsuccessfully read the actual value. Error message is roughly "Symbol not exist"

 

    variable = {
        'name': "SysMatrixRun.pp_R[0][1][1]",
        'addr': "SysMatrixRun.pp_R[0][1][1]",
        'type': 'float',
        'size': 4
    }
    await SendRequest(ws, 'DefineVariable', variable)
    data = await SendRequest(ws, 'ReadVariable', variable['name'])
    print(data)

 

In this case, even when using TSA, the variable "SysMatrixRun.pp_R[0][1][1]" cannot be read in the MASTER.

But after I changed to use this TSA, I was able to read "SysMatrixRun.pp_R[0][1][1]" in the MASTER.

FMSTR_TSA_STRUCT(_SYSTEM_MATRIX)

FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][0], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][1], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][2], FMSTR_TSA_FLOAT)
...
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[59][7], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[59][8], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[59][9], FMSTR_TSA_FLOAT)

FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[0], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[1], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[2], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[3], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[4], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[5], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[6], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[7], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[8], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_LC[9], FMSTR_TSA_FLOAT)

FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, YL, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, YC, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, YR, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, attr, FMSTR_TSA_UINT8)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, vhs, FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, J, FMSTR_TSA_FLOAT)
FMSTR_TSA_TABLE_END( )

FMSTR_TSA_TABLE_LIST_BEGIN( )
FMSTR_TSA_TABLE(first_table)
FMSTR_TSA_TABLE_LIST_END( )

I wonder if it's because the "lite" version is unable to interpret the writing style of multi-dimensional arrays like "[][]"?

If you need more test information, I will provide "the second"

 

0 Kudos
Reply
1,762 Views
iulian_stan
NXP Employee
NXP Employee

Thank you for details. I confirmed the issue on FreeMASTER Lite side - there is bug in expression evaluation (when it tries to convert the symbol to an address). It will be addressed it in the next release. 

Just to be clear - FreeMASTER nor FreeMASTER Lite cannot resolve multi dimensional arrays. That is why you could not use multiple indexes in the First scenario.

When you defined additional TSA Members such as:

FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][0], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][1], FMSTR_TSA_FLOAT)
FMSTR_TSA_MEMBER(_SYSTEM_MATRIX, pp_R[0][2], FMSTR_TSA_FLOAT)

each one is treated as separate symbol (not an actional multidimensional array). And FreeMASTER resolves SysMatrixRun.pp_R[0][1][k] address as SysMatrixRun.pp_R[0][1](symbol base address) + k(offset).

Usually, I would define variables using the first approach you described and compute the offset from matrix symbol:

addr: SysMatrixRun.pp_R[i][j][k] → SysMatrixRun.pp_R[i * d2 * d3 + j * d3 + k]

where d2, d3 are matrix dimension and can be computed either based on symbol size or using helper variables. The reason is that in order to emulate the access using independent indexes requires definitions of additional symbols (down to one dimensional arrays) which creates additional overhead if matrix dimensions change.

0 Kudos
Reply