I'm debugging a piece of code that is causing some crashes using Keil's compiler but not ARM-GCC. I'm not familiar with the history of the code but as I'm reading more I'm realizing that there is definitely at least a strict-aliasing violation in the code. However the error that drew me to the code in the first place was an unaligned access fault when running this snippet.
I'm embarassed to admit that I was not very aware of the issues with this kind of strict aliasing violation, and would like to convince myself that fixing that will solve the issue, and not just mask whatever is causing the unaligned fault.
- Could someone help me understand why I'm seeing the unaligned access fault? Is this related to the strict-aliasing violation and if so, how does that manifest as such? 
- What would the best way to resolve this be? I have declared sampleStruct as __packed now which appears to be working but would using a union for sampleStruct be a better solution? Or going further would I need to copy individual members of the struct? 
I'm still learning more about the strict-aliasing rules, but a push in the right direction would be much appreciated.
*Note: This is running on in an embedded system on a Cortex-M4 and will never run on another platform or hardware.
Disassembly:
    0x00031DF0 9802      LDR           r0,[sp,#0x08]
        64:             structA->SessionCount = params.SessionCount; 
    0x00031DF2 60A0      STR           r0,[r4,#0x08]
        65:             structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f; 
    0x00031DF4 9806      LDR           r0,[sp,#0x18]
        65:             structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f; 
    0x00031DF6 B140      CBZ           r0,0x00031E0A
        65:             structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f; 
    0x00031DF8 EDDD0A05  VLDR          s1,[sp,#0x14]
    0x00031DFC ED9D0A06  VLDR          s0,[sp,#0x18]
    0x00031E00 EEB81A40  VCVT.F32.U32  s2,s0
    0x00031E04 EE800A81  VDIV.F32      s0,s1,s2
    0x00031E08 E001      B             0x00031E0E
        65:             structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f; 
    0x00031E0A ED9F0A1E  VLDR          s0,[pc,#0x78]
>   0x00031E0E ED840A03  VSTR          s0,[r4,#0x0C]
        66:             structA->Value = params.ValueLast; 
    0x00031E12 ED9D0A04  VLDR          s0,[sp,#0x10]
    0x00031E16 ED840A04  VSTR          s0,[r4,#0x10]
        67:             structA->SessionValueLow = params.ValueLow; 
    0x00031E1A ED9D0A07  VLDR          s0,[sp,#0x1C]
    0x00031E1E ED840A05  VSTR          s0,[r4,#0x14]
        68:             structA->SessionValueHigh = params.ValueHigh; 
    0x00031E22 ED9D0A08  VLDR          s0,[sp,#0x20]
58  case SESSION_INFO_HDL: {
59      AppParams_t params;
60      AppParamsRead(¶ms);
61      sampleStruct_t *structA      = (sampleStruct_t *) &pData->pValue[offset];
62      structA->TotalCount          = params.TotalCount;
63      structA->SessionId           = params.SessionId;
64      structA->SessionCount        = params.SessionCount;
65      structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
66      structA->Value               = params.ValueLast;
67      structA->SessionValueLow     = params.ValueLow;
68      structA->SessionValueHigh    = params.ValueHigh;
69      structA->Reserved = 0;
70      AttsSetAttr(SESSION_INFO_HDL, sizeof(*structA), &pData->pValue[offset]);
71      break;
72  }
Code Snippet: https://godbolt.org/z/Djebj2
typedef struct
{
    uint8_t           *pValue;          /*!< \brief Pointer to the data's value */
    uint16_t          *pLen;            /*!< \brief Pointer to the length of the data's value */
} data_t;
typedef struct sampleStruct {
    uint32_t TotalCount;
    uint32_t SessionId;
    uint32_t SessionCount;
    float    SessionValueAverage;
    float    Value;
    float    SessionValueLow;
    float    SessionValueHigh;
    uint32_t Reserved;
} sampleStruct_t;
typedef struct AppParams {
    uint32_t TotalCount;
    uint32_t SessionId;
    uint32_t SessionCount;
    uint32_t CalibrationThreshold;
    float    ValueLast;
    float    ValueTotal;
    uint32_t ValueNum;
    float    ValueLow;
    float    ValueHigh;
} AppParams_t;
void function ( uint16_t offset, data_t * pData )
{
    AppParams_t params;
    sampleStruct_t *structA      = (sampleStruct_t *) &pData->pValue[offset];
    structA->TotalCount          = params.TotalCount;
    structA->SessionId           = params.SessionId;
    structA->SessionCount        = params.SessionCount;
    structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
    structA->Value               = params.ValueLast;
    structA->SessionValueLow     = params.ValueLow;
    structA->SessionValueHigh    = params.ValueHigh;
    structA->Reserved = 0;
    AttsSetAttr(SESSION_INFO_HDL, sizeof(*structA), &pData->pValue[offset]);
    send_data ( SESSION_INFO_HDL, &pData->pValue[offset], sizeof(*structA) );
}
 
     
    