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

Non aligned access in arm v7 going into exception

typedef struct __attribute__((__packed__))

{

uint8_t    op_code;

uint8_t    flags;

uint32_t   logical_block_addr;

uint8_t    group_num;

uint16_t   tx_length;

uint8_t    control;

} SCSI_READ10_t;

when I am assigning some value to tx_length core is showing some exception. Is the assembly of   tx_length assignment  compiler is putting strh/ldrh(half-byte) instruction throwing error its not 2 byte aligned . But not aligned accesses are enabled. So my question is : -

Q1. Can I access not aligned memory with strh/ldrh (suppose addr :- 0xxxx37) if non aligned accesses are enabled for core ?

Q2. Do compiler take care of these no aligned access and will convert not aligned half word into two  1 byte accesses ?

  • Q1. Can I access not aligned memory with strh/ldrh (suppose addr :- 0xxxx37) if non aligned accesses are enabled for core ?

    It depends how the memory pages are mapped. Unaligned accesses are not allowed to "strongly ordered" or "device" memory types, and will generate exceptions, even if the core has unaligned accesses enabled.


    Q2. Do compiler take care of these no aligned access and will convert not aligned half word into two  1 byte accesses ?

    The compiler can't know the page table settings, so it would be a global change for the whole program, but yes, I believe it is possible although I've not tried in years ...

    HTH,
    Pete

  • Hello,

    regarding Q2, GCC (I used ver. 4.9.3) converted ome 16bit access into two 8bit accesses.

    1) source code

    typedef struct __attribute__((__packed__))
    {
      uint8_t    op_code;
      uint8_t    flags;
      uint32_t   logical_block_addr;
      uint8_t    group_num;
      uint16_t   tx_length;
      uint8_t    control;
    } SCSI_READ10_t;
    volatile SCSI_READ10_t x;
    main()
    {
      x.tx_length=0x1234;
    }
    

    2) assembly code compiled

    main:
            mov     r1, #52
            mov     r2, #18
            ldr     r3, .L2
            ldrb    ip, [r3, #7]    @ zero_extendqisi2
            strb    r1, [r3, #7]
            ldrb    r1, [r3, #8]    @ zero_extendqisi2
            strb    r2, [r3, #8]
            bx      lr
    .L3:
            .align  2
    .L2:
            .word   x
            .size   main, .-main
            .comm   x,10,4
    

    Best regards,

    Yasuhiko Koumoto.

  • Generally speaking, enable data caching of that memory space is a good solution.

    As Yasuhiko showed, GCC may refine the assembly code for unaligned access.

    But I think it may rely on GCC version or build options and may impact performance.

    So my suggestion is:

    If you can, enable data cache and map that space to cacheable.

    If you cannot enable cache for that space:

    1 Search GCC documents for unaligned access conversion

    2 Byte copy this packed field to a buffered unpacked structure if it doesn't update frequently.