×
单片机 > 单片机程序设计 > 详情

ARMv7的非对齐地址访问

发布时间:2020-06-20 发布时间:
|
ARMv7默认支持非对齐地址访问,但有些条件:
CP15 的系统控制寄存器(SCTLR), bit.A = 0, (bit.U = 1, 对于ARMv7已经默认置1了,不可改). 
访问的地址空间必须为Normal memory, 访问Device memory或Strongly memory都会引发alignment fault的Data Abort。而如果MMU disable的话,所有的memory都被当作Strongly memory处理(这句话没找到出处,来自ARM support回复的mail)。所以MMU必须enable,memory类型由页表项的C, B, TEX[2:0]决定,这部分可以查阅 的: 

B3.7 Memory region attributes.


示例
        MRS     r0, CPSR
        ORR     r0, r0, #(PSR_I_BIT|PSR_F_BIT)  ; Disable IRQ & FIQ
        MSR     CPSR_c, r0
; Disable MMU stuff and caches
        MRC     p15, 0, r0, c1, c0, 0           ; read control register to r0
        BIC     r0, r0, #0x000f                 ; clear W(Write buffer), C(Cache), A(Align), M(MMU) bits
        BIC     r0, r0, #0x1100                 ; clear I(ICache), S(System protection) bits
        MCR     p15, 0, r0, c1, c0, 0           ; write control register.
                
stack_setup
        LDR     r0, =|Image$$ZI$$Limit|
        ADD     r0, r0, #STACK_SIZE_SVC
                
        MSR     CPSR_c, #(MODE_SVC :OR: PSR_F_BIT :OR: PSR_I_BIT)
        MOV     sp, r0
mmu_setup        
        LDR     r2, =MMU_TABLE_BASE                             ; mmu page base address
        MCR     p15, 0, r2, c2, c0, 0           ; write mmu page base address
                
        BL      _cpu_mmu_init
        
                
        LDR     r0, =0x89
        LDRH    r1, [r0]

关于编译器

在Realview下,如果目标处理器选择了ARMv6、ARMv7-A(如Cortex-A8)、ARMv7-R,编译器的缺省选项是--unaligned_access, 而如果选择了ARMv6以前的版本,或ARMv7-M体系的处理器,缺省选项是--no_unaligned_access。

对于选项--no_unaligned_access,编译器会自动将C语言对非对齐地址的变量的访问,转化成若干个字节操作。 比如:

__packed struct usb_endpoint_descriptor {
    u8 bLength;
    u16 wMaxPacketSize;
    u8 bDescriptorType;
    u8 bEndpointAddress;
    u8 bmAttributes;
    u8 bInterval;
} ;
int main(void)
{   
    volatile struct usb_endpoint_descriptor ep;
   
    ep.wMaxPacketSize = 0x200;
    while(1);
    return 0;
}
如果--no_unaligned_access选项编译,它的反汇编代码如下:
    main
        0xe100c5f0:    e92d400c    .@-.    PUSH     {r2,r3,lr}
        0xe100c5f4:    e3a00c02    ....    MOV      r0,#0x200
        0xe100c5f8:    e5cd0001    ....    STRB     r0,[sp,#1]
        0xe100c5fc:    e1a00420     ...    LSR      r0,r0,#8
        0xe100c600:    e5cd0002    ....    STRB     r0,[sp,#2] 
        0xe100c604:    eafffffe    ....    B        0xe100c604 ; main + 20
如果是--unaligned_access选项编译,它的反汇编代码如下:
    main
        0xe100c5f0:    e92d400c    .@-.    PUSH     {r2,r3,lr}
        0xe100c5f4:    e3a00c02    ....    MOV      r0,#0x200
        0xe100c5f8:    e1cd00b1    ....    STRH     r0,[sp,#1] 
        0xe100c5fc:    eafffffe    ....    B        0xe100c5fc ; main + 12

如果你的目标平台是ARMv6或ARMv7-AR,但是在你的代码中,MMU是disable的,那你应该手动添加编译选项--no_unaligned_access,让编译器来帮你处理非对齐访问。

关键字:ARMv7  非对齐  地址访问 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析