2013-12-16 1 views
0

Im совершенно новый для языка ассемблера и только что купил малиновый пи. Я знаю, что я могу использовать ОС и начинать программирование с помощью python и т. Д., Но я хотел бы взглянуть глубже. Поскольку моя малина pi еще не пришла, я не могу проверить код asm. В уроке OK03 я просмотрел расширение (download), я попытался понять его сам, но я столкнулся с этой проблемой: почему gpioAddr str'ed на pinFunc в конце (опять же)? Я взял первый вызов в main.s, как, например, чтобы положить мои комментарии:«Baking Pi: OK03» - Не понимаю функции

pinNum .req r0 
pinFunc .req r1 
mov pinNum,#16 
mov pinFunc,#1 
bl SetGpioFunction 
.unreq pinNum 
.unreq pinFunc 

SetGpioFunction:

/* NEW 
* SetGpioFunction sets the function of the GPIO register addressed by r0 to the 
* low 3 bits of r1. 
* C++ Signature: void SetGpioFunction(u32 gpioRegister, u32 function) 
*/ 
.globl SetGpioFunction 
SetGpioFunction: 
    pinNum .req r0 
    pinFunc .req r1 
    cmp pinNum,#53 
    cmpls pinFunc,#7 
    movhi pc,lr 

    push {lr} 
    mov r2,pinNum 
    .unreq pinNum 
    pinNum .req r2 
    bl GetGpioAddress 
    gpioAddr .req r0 

    functionLoop$: 
     cmp pinNum,#9 
     subhi pinNum,#10 
     addhi gpioAddr,#4 
     bhi functionLoop$ 

    /* pinNum = 6 
     gpioAddr = 0x20200004 
    */ 

    add pinNum, pinNum,lsl #1 
    /* 
     pinNum = 18 (10010) 
    */ 
    lsl pinFunc,pinNum 
    /* 
     pinFunc = 1000000000000000000 
    */ 

    mask .req r3 
    mov mask,#7     /* r3 = 111 in binary */ 
    /* 
     mask = 111 
    */ 
    lsl mask,pinNum    /* r3 = 11100..00 where the 111 is in the same position as the function in r1 */ 
    /* 
     mask = 111000000000000000000 
    */ 
    .unreq pinNum 

    mvn mask,mask    /* r3 = 11..1100011..11 where the 000 is in the same poisiont as the function in r1 */ 
    /* 
     mask = 11..11000111111111111111111 
    */ 
    oldFunc .req r2 
    ldr oldFunc,[gpioAddr]  /* r2 = existing code */ 
    /* 
     oldFunc = 0x12 + (gpioaddr)0x20200004 = 0x20200016 
     oldFunc = 100000001000000000000000010110 
     mask = 111111111000111111111111111111 
    */ 
    and oldFunc,mask   /* r2 = existing code with bits for this pin all 0 */ 
    /* 
     oldFunc = 100000001000000000000000010110 
    */ 
    .unreq mask 

    /* 
     pinFunc = 000000000001000000000000000000 
     oldFunc = 100000001000000000000000010110 
    */ 
    orr pinFunc,oldFunc   /* r1 = existing code with correct bits set */ 
    /* 
     pinFunc = 100000001001000000000000010110 
     pinFunc = 0x20240016 
    */ 
    .unreq oldFunc 

    str pinFunc,[gpioAddr] 
    /* 
     Why do we add gpioaddr again? 
     pinFunc = 0x40440016 
    */ 
    .unreq pinFunc 
    .unreq gpioAddr 
    pop {pc} 

Что я получаю здесь не так? Заранее спасибо.

ответ

1
read the old setting for this register 
ldr oldFunc,[gpioAddr]  /* r2 = existing code */ 
mask off, zero out the bits we want to change, leaving the others unchanged 
and oldFunc,mask   /* r2 = existing code with bits for this pin all 0 */ 
or in the new bits we want to change the ones related to the pin in question 
orr pinFunc,oldFunc   /* r1 = existing code with correct bits set */ 
write the new value to the register so the changes for that pin function take effect 
str pinFunc,[gpioAddr] 

это простая функция чтения-изменения-записи.

+0

Спасибо, это немного меня очистило - я просто предположил, что мы что-то пишем в pinFunc, а не в том, что мы храним pinFunc. – Jan

+0

Это немного исключение из правила, обычно вещь слева - это пункт назначения и вещь справа от источника, но для хранилища она остается справа не справа налево. –

Смежные вопросы