Dealing with data serialization without violating the strict aliasing rule

前端 未结 2 527
慢半拍i
慢半拍i 2021-01-23 21:37

Often in embedded programming (but not limited to) there is a need to serialize some arbitrary struct in order to send it over some communication channel or write t

2条回答
  •  走了就别回头了
    2021-01-23 21:58

    Consider that writing to eeprom is often slower, sometimes a lot slower, than writing to normal memory, that using an intervening buffer is rarely a performance drag. I realize this goes against this comment, yet I feel it deserves consideration as it handles all other C concerns

    Write a helper function that has no alignment, aliasing nor size issues

    extern void write_to_eeprom(/* I'd expect const */ uint32_t *data, uint32_t len);
    
    // Adjust N per system needs
    #define BYTES_TO_EEPROM_N 16
    
    void write_bytes_to_eeprom(const void *ptr, size_t size) {
      const unsigned char *byte_ptr = ptr;
      union {
        uint32_t data32[BYTES_TO_EEPROM_N / sizeof (uint32_t)];
        unsigned char data8[BYTES_TO_EEPROM_N];
      } u;
    
      while (size >= BYTES_TO_EEPROM_N) {
        memcpy(u.data8, byte_ptr, BYTES_TO_EEPROM_N);  // **
        byte_ptr += BYTES_TO_EEPROM_N;
        write_to_eeprom(u.data32, BYTES_TO_EEPROM_N / sizeof (uint32_t));
        size -= BYTES_TO_EEPROM_N;
      }
    
      if (size > 0) {
        memcpy(u.data8, byte_ptr, size);
        while (size % sizeof (uint32_t)) {
          u.data8[size++] = 0;  // zero fill
        }
        write_to_eeprom(u.data32, (uint32_t) size);
      }
    }
    
    // usage - very simple
    write_bytes_to_eeprom(&s, sizeof s);
    

    ** Could use memcpy(u.data32, byte_ptr, BYTES_TO_EEPROM_N); to handle @zwol issue.

提交回复
热议问题