Get value from structure memory abnormal based on FX3

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Wutian
Level 1
Level 1
First reply posted First question asked Welcome!

Recently I do some experiment on FX3, found an abnormal result with my code.

I have do experiments on both FX3 and STM32F730. the common codes as below:

/*----------------------------------------------------------------------------
My test function
*---------------------------------------------------------------------------*/
typedef struct
{
unsigned short usSyncCode;
union
{
unsigned char uchCmdCode;
unsigned char uchCmdRspCode;
};
unsigned char uchOptCode;
unsigned char uchValidDataLen;
unsigned char uchPayloadArr[20];
}__attribute__((packed)) ST_ALIGNMENT_TEST;

ST_ALIGNMENT_TEST stAlignTestStructure = {0};
void myTestFunc()
{
/* Initialize tested structure memory */
uint8_t uchSize = sizeof(stAlignTestStructure);
uint8_t* puchTemp = (uint8_t*)&stAlignTestStructure;
uint8_t i = 0;
for (i = 0; i < uchSize; i++)
{
puchTemp[i] = i;
}
#if TEST_BIT16
uint16_t* pusPayVal = (uint16_t*)stAlignTestStructure.uchPayloadArr;
uint16_t usPayVal1 = pusPayVal[0];
uint16_t usPayVal2 = pusPayVal[1];
usPayVal1 = usPayVal2;
usPayVal2 = usPayVal1;
#else
uint32_t* pusPayVal = (uint32_t*)stAlignTestStructure.uchPayloadArr;
uint32_t usPayVal1 = pusPayVal[0];
uint32_t usPayVal2 = pusPayVal[1];
usPayVal1 = usPayVal2;
usPayVal2 = usPayVal1;
#endif
}

For FX3, I think the result is abnormal:

- If  BIT_16=1:  usPayVal1=0x0504, usPayVal2=0x0706

- For BIT_16=0: usPayVal1=0x04070605, usPayVal2=0x080B0A09. 

For STM32F730, the result is as expeted.

- If  BIT_16=1:  usPayVal1=0x0605, usPayVal2=0x0807

- For BIT_16=0: usPayVal1=0x08070605, usPayVal2=0x0C0B0A09.

I  have used __attribute__((packed)) in the structure definition,  so I think it may not the issue of alignment, but why FX3 result still not compose the target value starting from the pointer and from low address to high address?

Do you guys know the reason, if you know pls give your answer, appreciate~

0 Likes
1 Solution
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

I found an article with similar issue Documentation – Arm Developer 

As you mentioned, from the above article says that by default, ARM7 and ARM9 based microcontrollers do not allow un-aligned accesses to 16-bit and 32-bit data types.

Regards,
Rashi

View solution in original post

0 Likes
5 Replies
Wutian
Level 1
Level 1
First reply posted First question asked Welcome!

After initialization, the memory of global structure is : 0x00,0x01,0x02,0x03,0x04,...,0x19.  structure size is 0x1A.

0 Likes
lock attach
Attachments are accessible only for community members.
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

I tried to use the below snippet and got the attached results. Please enable the debug prints to check the initialized value. As union is used in the structure, please refer to initialized values in the attached snippet

 

typedef struct
{
unsigned char usSyncCode;
union
{
unsigned char uchCmdCode;
unsigned char uchCmdRspCode;
};
unsigned char uchOptCode;
unsigned char uchValidDataLen;
unsigned char uchPayloadArr[20];
} __attribute__((packed)) ST_ALIGNMENT_TEST; 

ST_ALIGNMENT_TEST stAlignTestStructure = {0};
void myTestFunc()
{
/* Initialize tested structure memory */
uint8_t uchSize = sizeof(stAlignTestStructure);
uint8_t * puchTemp;
 puchTemp = (uint8_t*)&stAlignTestStructure;
uint8_t i = 0;
for (i = 0; i < uchSize; i++)
{
puchTemp[i] = i;
//CyU3PDebugPrint (4, "\n\r usSyncCode = %d, uchCmdCodeuch = %d, CmdRspCode = %d, uchOptCode =%d, uchValidDataLen = %d,uchPayloadArr[i] =%d \n \r",stAlignTestStructure.usSyncCode,stAlignTestStructure.uchCmdCode,stAlignTestStructure.uchCmdRspCode,stAlignTestStructure.uchOptCode,stAlignTestStructure.uchValidDataLen,stAlignTestStructure.uchPayloadArr[i] );
}
#ifdef TEST_BIT16
uint16_t usPayVal1 =0;
uint16_t usPayVal2 =0;
uint16_t* pusPayVal = (uint16_t*)stAlignTestStructure.uchPayloadArr;
usPayVal1 = pusPayVal[0];
usPayVal2 = pusPayVal[1];
#else
uint32_t usPayVal1 =0;
uint32_t usPayVal2 =0;
uint32_t* pusPayVal = (uint32_t*)stAlignTestStructure.uchPayloadArr;
 usPayVal1 = pusPayVal[0];
 usPayVal2 = pusPayVal[1];

#endif

CyU3PDebugPrint (4, "\n\n   usPayVal1 = 0x%x  usPayVal2 = 0x%x \r\n",usPayVal1 , usPayVal2);
}

Please let me know if further queries

Regards,
Rashi
0 Likes

Thanks for your reply.

With your modified code snippet, my result is the same with yours, and I have checked data memory in eclipse IDE, the structure memory initialized correct.

But my original question still there, because in my original code, usSyncCode is defined with type  uint16_t not uint8_t. With the same original code, the result on STM32 and FX3 are different,  the result on STM32 is as my expected, but the FX3 result I don`t know how to explain why.

0 Likes
Wutian
Level 1
Level 1
First reply posted First question asked Welcome!

STM32F7 use Cortex-M7 core, which use ARMv7E-M architecture, this architecture support unaligned memory access.

FX3 use ARM926EJ-S core, which use ARMv4T architecture, it`s released at 2008, maybe it not support unaligned memory access.

This is my current opinion.

0 Likes
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

I found an article with similar issue Documentation – Arm Developer 

As you mentioned, from the above article says that by default, ARM7 and ARM9 based microcontrollers do not allow un-aligned accesses to 16-bit and 32-bit data types.

Regards,
Rashi
0 Likes