Problem with volatile struct - I get hard fault

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

Problem with volatile struct - I get hard fault

2,364 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klatecki on Fri Oct 07 06:14:35 MST 2011
I have simple code:

#pragma pack(push,1)
typedefstruct
{
char char1;
short short1;
} test_struct_t;
#pragma pack(pop)

volatile char char1;
volatile short short1;
volatile test_struct_t test;

int main(void) {

char1 = 1;
short1 = 256;

test.char1 = char1;
test.short1 = short1;

char1 = test.char1;
[COLOR=Red]short1 = test.short1;[/COLOR]

for(;;);

return 0 ;
}


and at line colored red I get HardFault,
but when test variable isn't volatile that code works.

Problem occurs with both processors M0 and M3, with and without optimization

I have LPCXpresso 4.0.7.
If I remember correctly this code works with LPCXpresso 3.x.x
0 Kudos
Reply
13 Replies

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ToBeFrank on Mon Oct 10 11:15:38 MST 2011

Quote: CodeRedSupport
I suspect that you might be hitting some subtle difference in behaviour between these two ways of packing structures.



I don't agree. The compiler was nice enough to point out his problem. Since the struct is packed, an access to the field is unaligned and thus requires more than one memory access to get it's value. Since he marked it volatile, the compiler has to make a choice between accessing it with one unaligned memory access or two aligned memory accesseses. It has informed him that it chose to honor his volatile and do one unaligned memory access. Thus, hard fault.
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Mon Oct 10 07:50:20 MST 2011

Quote: klatecki
and at line colored red I get HardFault,
but when test variable isn't volatile that code works.

Problem occurs with both processors M0 and M3, with and without optimization

I have LPCXpresso 4.0.7.
If I remember correctly this code works with LPCXpresso 3.x.x



So with LPCXpresso 3.6.3, you get the following warning....
../src/main.c:1: warning: #pragma pack(push[, id], <n>) is not supported on this target
which would explain why you  saw different behaviour - as you weren't packing anything with the earlier tools!

It is also worth saying that using your original test code on LPCXpresso 4.1.0, I don't see any hard fault running the code here on Cortex-M3 (on an LPC1768), though I do get the hard fault on Cortex-M0 (on an LPC1114). This matches with what I might expect, as Cortex-M3 can do unaligned accesses, whereas Cortex-M0 can't.

I suspect that it might be worth looking at using [FONT=Courier New][SIZE=2] [FONT=monospace][/FONT]__attribute__ ((packed))[/SIZE][/FONT] rather than the pragmas you are currently using.

http://support.code-red-tech.com/CodeRedWiki/PackedStructs

I suspect that you might be hitting some subtle difference in behaviour between these two ways of packing structures.

Regards,
CodeRedSupport
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by igorsk on Mon Oct 10 04:26:54 MST 2011

Quote: klatecki
I understand this but I think compiler should knows that Cortex M0 don't support mis-aligned read and should use multiple reads instead of use incorrect instruction that cause Hard Fault


The compiler can't know what you intend. Since the structure is volatile, it [I]probably[/I] means that field accesses should be atomic, and that's what it's trying to do here.

Quote: klatecki

In the specific (more complex) situations (eg, casting the raw data buffer on the structure), the compiler does not report warning. I will try to create such an example in which the compiler will not warn you and still be an issue.


Use memcpy to a local variable if you're not sure of the original alignment.
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klatecki on Fri Oct 07 22:54:07 MST 2011

Quote: TheFallGuy
Can't you disable the unaligned access fault in the cortex-m3 confit register?



Unaligned accesses with LDM, STM, LDRD, and STRD instructions always generate a Hard Fault even when UNALIGN_TRP is set to 0.
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Fri Oct 07 15:26:01 MST 2011
Can't you disable the unaligned access fault in the cortex-m3 confit register?
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Oct 07 12:39:11 MST 2011
Don't think so :)

I would bet 1000€ a simple structured access to your unique_id could be programmed within 5 minutes :eek:
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klatecki on Fri Oct 07 12:31:08 MST 2011

Quote: Zero
What's wrong with using unions :confused:



Nothing is wrong, but if I throw all the structures to the union I get big creature long to 500 lines or more difficult to comprehend.
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Oct 07 12:17:34 MST 2011
What's wrong with using unions :confused:
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klatecki on Fri Oct 07 12:16:14 MST 2011

Quote: Zero
Hello?

What else should I say to that? What are you trying to do?
Kidding a compiler or reading a structure in a structure?



GARMIN_DATA is the main structure. Depending on FMPID meaning of FMPDATA is different. I want to cast FMPDATA to other structure like CToS_Text (I have tens this like sub structures) and read information.

Compiler should know what is the address of each field and correctly read data. I do not care or do it with a single command or a few readings of individual bytes. The result will be correct and the operation should not cause exceptions.
I think the compiler is doing it wrong :(

Is there any way to force the compiler to generate the correct code? Any flag, directive or something.
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Oct 07 11:56:01 MST 2011

Quote: klatecki
What do you say to that?



Hello?

What else should I say to that? What are you trying to do?
Kidding a compiler or reading a structure in a structure?
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klatecki on Fri Oct 07 10:24:55 MST 2011
What do you say to that?

#include <stdint.h>

#pragma pack(push,1)

typedef struct {
uint8_t DLE;    //Data Link Escape = 0x10
uint8_t PID;    //Packet ID
uint8_t SIZE;   //Size of packet
uint16_t FMPID;
uint8_t  FMPDATA[251];
}GARMIN_DATA;

#pragma pack(pop)

typedef struct {

    uint32_t  origination_time;
    int32_t   lat;
    int32_t   lon;
    uint32_t  unique_id;
    uint8_t  id_size;
    uint8_t  reserved[3]; /* set to 0 */
    uint8_t  id[16];
    uint8_t  text_message[200];

}CToS_Text;     //Client to Server Text


GARMIN_DATA garmin;

int main(void) {

uint32_t id = 0;

id = ((CToS_Text *)garmin.FMPDATA)->unique_id;

for(;;);

return 0 ;
}
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klatecki on Fri Oct 07 10:01:39 MST 2011

Quote: Zero
Do you understand that :confused:

So your compiler isn't very happy with your struct :mad:




I understand this but I think compiler should knows that Cortex M0 don't support mis-aligned read and should use multiple reads instead of use incorrect instruction that cause Hard Fault


Quote: Zero

Changing it to...
typedef    struct
{
 short short1;
 char char1;
} test_struct_t;
...could help



Unfortunately I can't reorder fields in the structure

OK, I agree with the fact that the compiler warns against the mistake but this is just an example that I created to illustrate the problem.
In the specific (more complex) situations (eg, casting the raw data buffer on the structure), the compiler does not report warning. I will try to create such an example in which the compiler will not warn you and still be an issue.
0 Kudos
Reply

2,212 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Oct 07 06:49:15 MST 2011
Do you understand that :confused:


Quote:

../src/main.c:47:15: warning: mis-aligned access used for structure member
../src/main.c:47:15: note: When a volatile object spans multiple type-sized locations, the compiler must choose between using a single mis-aligned access to preserve the volatility, or using multiple aligned accesses to avoid runtime faults.  This code may fail at runtime if the hardware does not allow this access.

So your compiler isn't very happy with your struct :mad:

Changing it to...
typedef    struct
{
 short short1;
 char char1;
} test_struct_t;
...could help
0 Kudos
Reply