This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

unaligned double data access in DM8168



during network packet prase, we make a pointer from packet buffer usually, but if this is a double field and the memory is not 4 byte aligned, the next operation to the pointer will cause task hang. for example:

// the packet buffer is 4 bytes align char buffer[1024];   // we assume buffer equ 0x80010000 double * p_ratio = (double *)(buffer+3); *p_ratio = 0.0;   // task will hang here

Our source code is come from a X86 based module, and there are too many unaligned double access.

is there any way to fix it?

  • let me confirm your following speaking, did you mean the hang occur in line B instead of line A ??  did you make sure if the buffer is really 4-byte align??  did you mean p_ratio is still 4-byte align?

    // the packet buffer is 4 bytes align char* buffer[1024];   

    // we assume buffer equ 0x80010000

    double * p_ratio = (double *)(buffer+3);    ---> line A

    *p_ratio = 0.0;   // task will hang here     --->  line B

      

  • I'm sorry for the first code, buffer is not a char* array. My test code is here

    #include <stdio.h>

    int main()

    {

      unsigned char  buffer[1024] = {0};

      double* p_ratio;

     

      printf("4 bytes align\n");

      p_ratio = (double*)buffer;

      printf("write value\n");

      *p_ratio = 1.0;

     

      printf("4 bytes unalign\n");

      p_ratio = (double*)(buffer+3);

      printf("write value\n");

      *p_ratio = 1.0;                    // task hang this line

     

      printf("test over\n");

     

      return 0;

    }

    The result is :

    4 bytes align

    write value

    4 bytes unalign

    write value

     

    the last printf statement is not be run.

     

     

     

     

  • pls add following and show us the result

       printf("buffer = 0x%x", buffer);
     
       printf("4 bytes align\n");

  • Not quite sure what you are trying to test with the test code. The first and second double values overlap. Each double value is 8 bytes. If this is just a test, and the odd byte offset is arbitrary then I have doubts that the compiler can be configured to handle unaligned doubles. The base address of buffer can be unaligned for doubles and the first access will fail instead of the second. You lucked out and your test resulted in aligned base address. Once you cast a pointer to double*, the compiler assumes that the address is properly aligned for double.

    Using memcpy to access unaligned data

    unsigned char  buffer[1024] = {0};
    double ratio = 1.0;
    mempcy(buffer  , &ratio, sizeof(double);
    mempcy(buffer+9, &ratio, sizeof(double);

    Using packed structure for unaligned data.

    typedef struct
    {
      double x; // Offset 0
      char   y; // Offset 8
      double z; // Offset 9
    } __attribute__((packed)) BUFFER;

    BUFFER buffer;
    buffer.x = 1.0;
    buffer.z = 1.0;

    Compiler must support the packed attribute.

    You should post in the Development Tools->TI C/C++ Compiler to see if there is a compiler feature that handles unaligned pointers. Which processor are you using? ARM? DSP? The compiler features will be different for each.

    EDIT: Oops fix double is 8 and float is 4.