Home > Enterprise >  uint32_t pointer causes hardfault error in STM32L053 . How to align this 32 bit pointer?
uint32_t pointer causes hardfault error in STM32L053 . How to align this 32 bit pointer?

Time:04-14

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.

My code always calls the void pass_Init(uint32_t * pass) //pass is the address of 32 bit password being passed { password= pass; //no issues here } before doing any comparisons or assignments for that pointer. Even if I initialize my pointer as uint32_t * password = 0; I still get the hardfault error while comparing (although debugger shows *password has the correct value just before debugging) As far as I see, this seems like a problem where there is unaligned access to my uint32_t * pointer

CodePudding user response:

Dereferencing a null or uninitialized pointer will invoke undefined behavior. There are several scenarios where this could happen in the code you have shown. Note that:

uint32_t * password;//creates an uninitialized pointer

At any point beyond the declaration of this pointer, the expression *password is an int, and more importantly indicates the pointer password, is being dereferenced. So, depending on whether password is null (or initialized) at this point, it could be dereferencing a null (or uninitialized) pointer. At that point, a seg-fault could occur.

uint16_t PasswordEnter(void)
{
    return (*password== PASSWORDC); //causes hardfault error due to alignment issues
}

//exact same thing here:

void wipe(void){
    *password= 0; //causes hardfault error due to alignment issues
}

CodePudding user response:

It appears that you have a problem with having one too many levels of indirection everywhere.

If the password is 32 bits and you want to store it in a global variable then store it in a global uint32_t, not a global uint32_t pointer.

Change the declaration of password from:

uint32_t * password;

to:

uint32_t password;

Now change the declaration of pass_Init:

void pass_Init(uint32_t pass)
{
  password = pass;
}

And your other functions as follows:

bool PasswordEnter(void)
{
  return (password == PASSWORDC);
}

void wipe(void)
{
   password = 0;
}

Change the calling code (provided in comments) from:

pass_Init (&(UserPassword));

to

pass_Init (UserPassword);

Doing in this way results in simpler code at every line.

  • Related