cancel
Showing results for 
Search instead for 
Did you mean: 

uint32_t pointer causes hardfault error. How to align this 32 bit pointer for STM32L0 series?

AVals.1
Associate II

I have a 32 bit pointer which saves a password passed through a function and this password is used to compare to the saved password that I have.

uint32_t * password;

#define PASSWORDC 0x3f44d112

void pass_Init(uint32_t * pass) //pass is the address of 32 bit password being passed

{

   password= pass; //no issues here

}

uint16_t PasswordEnter(void)

{

   return (*password== PASSWORDC); //causes hardfault error due to alignment issues

}

void wipe(void){

*password= 0; //causes hardfault error due to alignment issues

}

As I have added in comments, that the assignment of value works, in fact while debugging, I see that in void pass_Init(uint32_t * pass) the password gets the correct value to be assigned to it.

The issue happens if I do the comparison or any other operation which has *password = <something> line to it. So it definitely seems to be an issue with alignment.

Please let me know how could I solve this.

I know I can use something like __attribute__((packed, aligned(4))) , but I'm not sure how exactly to use it.

6 REPLIES 6

Allocation methods should produce 32-bit aligned addresses, where you run into problems is with randomly parsing data from things on 8-bit buffers, and alignment, like data read from a file or stream, or where you're using tightly packed structures, with is atypical for 32-bit compilers, and generally has to be forced.

Problem here is you've got an EQUAL SIGN and a SEMICOLON, so it's not a clean substitution, I'm honestly surprised this even compiles

#define PASSWORDC = 0x3f44d112;

This is the expectation your code example really has

#define PASSWORDC 0x3f44d112

void pass_Init(uint32_t * pass) //pass is the address of 32 bit password being passed

{

   memcpy(password, pass, sizeof(uint32_t)); // perhaps a method like this, or a specialize memcpy_unaligned() to handle cases where pass isn't 32-bit aligned

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks for the quick reply.

Sorry I had copied it wrong I was actually doing the allocation without the = and semicolon and have corrected that in the question.

I'm sorry I didn't really understand this part

memcpy_unaligned() to handle cases where pass isn't 32-bit aligned

I already tried the

memcpy(password, pass, sizeof(uint32_t)); // perhaps a method like this, or a specialize

in pass_Init, it gives no error here (which it doesn't also give an error during direct assignment

password= pass; //no issues here

The problem occurs in

uint16_t PasswordEnter(void)

{

   return (*password== PASSWORDC); //causes hardfault error due to alignment issues

}

And this problem persists even if I use memcmp instead of ==

Basically anywhere I'm using *password or any *<uint32_tPointer>

Where it's faulting doesn't make sense.

Look at the assembler code generated, and why that might be occurring, along with the addresses involved.

I don't even think the casting to uint16_t should be an issue here as you're doing a boolean test.

Assuming you're not providing adequate context to understand the true cause of the issue as described.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Yes it's not relevant to the casting of uint16_t or where.

I'm saying that using the *password or even any other (uint32_t * pointerexample) with value like *pointerexample = something or *pointerexample == something or something = *pointerexample causes the issue.

its using the uint32_t * pointer in any operation that causes the issue.

I read up on some other questions that some ARM cortexes especially M0 don't handle alignment for 32 bit variables, and to solve this you need to use either packing and align attributes or get32 and put32, but I couldn't figure out how

You've got to inspect what's actually faulting.

The CM0(+) is intolerant to reads/writes spanning multiple 32-bit words.

Without knowing the address held IN "password" pointer

This should fault

password = &variable_at_unaligned_address;

*password = 123; // will fault

This should not

uint32_t pass;

uint32_t *password = &pass;

*password = 123;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

uint16_t PasswordEnter(void)

{

if ((uint32_t)password & 3)

{

printf("%p misaligned\n", password);

return(0);

}

   return (*password== PASSWORDC); //causes hardfault error due to alignment issues

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..