This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Type struct pointer issue

Hello,
I'm stuck with hardfault handler.

When I try to execute read value from pointer address:

struct S2E_Packet { uint8_t module_type[3]; uint8_t fw_ver[3];
} __attribute__((packed)) S2E_Packet;

struct S2E_Packet s2e_packet;

AddressSrc=(uint32_t)&s2e_packet;
uint32_t test = *(uint32_t*)AddressSrc;
HAL_FLASH_Unlock();
HAL_FLASH_Program(TYPEPROGRAM_WORD, AddressDes, test);

program goes to hardfault handler.
No errors or warnings during compilation.

I have no idea.....

Parents
  • Thanks for answer.
    I know that maybe this kind of pointer cast is "brutal" way but I just want to read struct value in memory area and simply doesn't care what is in the struct value.

    Pier,
    Can You tell me where I can find more about Cortex-M0 unaligned 32-bit limit?
    It is sth new for me.

    Thanks everybody for answers.

Reply
  • Thanks for answer.
    I know that maybe this kind of pointer cast is "brutal" way but I just want to read struct value in memory area and simply doesn't care what is in the struct value.

    Pier,
    Can You tell me where I can find more about Cortex-M0 unaligned 32-bit limit?
    It is sth new for me.

    Thanks everybody for answers.

Children
  • Just make sure you align the data at an address evenly dividable by 4. Or make use of a uint8_t pointer to extract the four bytes and then combine them into a uint32_t value.

    The memory controller on x86 systems is nice and hides issues with unaligned data (except for potential bandwidth loss). But lots of 32-bit processors do not have a nice memory controller that makes two 32-bit accesses to be able to combine some bytes from the first word and some bytes from the second word before handing over to the processor core.

    The compiler+linker will normally align the data. When the compiler sees that data is packed, then it knows it can't trust the data to be properly aligned so it will instead produce alternative (larger/slower) code that can handle unaligned accesses. But your type cast throws away that attribute so the compiler assumes the pointer points to aligned data and is safe to use as-is.

  • __attribute__((packed))   and  __packed are very similar, but not the same.
    
    struct S2E_Packet
    {
       uint8_t module_type[3];
       uint8_t fw_ver[3];
       uint32_t uint1;   // &se2_Packet.uint1 gives you a (uint32_t *)
    } __attribute__((packed)) S2E_Packet;
    
    __packed struct S2E_Packet
    {
        uint8_t module_type[3];
        uint8_t fw_ver[3];
        uint32_t uint1;  // &se2_Packet.uint1 gives you a (__packed uint32_t *)
    } S2E_Packet;
    
    
    If you use the following cast, it works with aligned or un-aligned data. No Hard Fault.
    uint32_t test = *(__packed uint32_t*)AddressSrc;
    
    
    
    
    Google "Cortex-M0 data alignment" and you will get good information
    
    
    

  • I just want to read struct value in memory area and simply doesn't care what is in the struct value.

    If that's what you're trying to do, how did pointers to 32-bit integers even enter the picture? There's nothing related uint32_t in that job description. A uint32_t isn't even big enough to hold all the bytes of the existing struct.

    If all you want to do is move sequences of bytes from one place to the another, use (void *) for passing around the pointers, and (uint8_t *) to actually access the data. That's what they exist for. There's no point even thinking about (uint32_t *) for this.

  • Solution with "__packed uint32_t*" works like a charm;)
    Now I can read memory area of struct value in 4 byte sequence and use for flash write function.

    Many thaks for all advices.