assembly i/o driversweems/homepage/335-notes... · 2020. 6. 17. · • initialize before loop...

46
Assembly I/O Drivers How the Hardware Really Gets Data to the Outside

Upload: others

Post on 07-Feb-2021

0 views

Category:

Documents


0 download

TRANSCRIPT

  • Assembly I/O DriversHow the Hardware Really Gets Data to the Outside

  • Sample ProgramIn mbed compiler, select Import, search for asm

    Select C_to_asm

  • .s File

  • .cpp File

  • Run• Compile (may need to update library)

    • Download

    • Reset and run

    • Blinks LED1 and LED4 alternately

    • LED1 is controlled by assembly

    • LED4 by C

  • What’s Happening?

    • The LEDs are on GPIO ports

    • GPIO can be set to various modes, such as Digital In, Digital Out, Analog In or Out

    • The C++ program initializes the ports to Digital Out when it instantiates the LEDs

    • Ports are controlled by memory mapped registers

  • LPC1768 Memory Mapwww.nxp.com/documents/user_manual/UM10360.pdf

    page 13

    http://www.nxp.com/documents/user_manual/UM10360.pdf

  • What’s Where?• Memory map specifies the area for GPIO registers, but what are their

    addresses?

    • Need to look in Chapter 9 of the NXP manual, starting on p. 120

    • There are 5 ports each with various pins

  • Ports and Pins

    • Each port has a set of control registers

    • Within each control register, the bit number corresponds to a pin number

    • For example, pin 17 is represented by bit 17 in each of the control registers for the port

  • Control Registers5 kinds: FIODIR, FIOMASK, FIOPIN, FIOSET, FIOCLR

  • FIOPIN

  • FIOSET, FIOCLR

  • Address Pattern

    • FIODIR 0x2009C020 (base)

    • FIOMASK 0x2009C030 (base +10)

    • FIOPIN 0x2009C034 (base +14)

    • FIOSET 0x2009C038 (base +18)

    • FIOCLR 0x2009C03C (base +1C)

  • So, what pins are the LEDs on?• Ahh, that’s not in the LPC1768 manual

    • LPC1768 is an NXP chip

    • It’s port pins are logical, and connect to physical pins on the chip package

    • What the physical pins connect to depends on the board that holds it

    • Need to go to mbed documentation

  • Logical/Physical Pins

    From mbed user Nenad Milosevic

  • http://mbed.org/users/Lerche/notebook/lpc1768-pin-functions/

  • More Infohttp://mbed.org/users/Lerche/notebook/lpc1768-pin-functions/

    http://mbed.org/users/Lerche/notebook/lpc1768-pin-functions/

  • LEDs are on Port 1

    ; Load GPIO Port 1 base address in register R1 LDR R1, =0x2009C020 ; 0x2009C020 = GPIO port 1 base address

    Now we can see what this line of code does:

  • Within Port 1

    LEDs are on pins 18, 20, 21, and 23

    ; Move bit mask in register R0 for bit 18 only MOV.W R2, #0x040000 ; 0x040000 = 1

  • Set Up for Set/Clear; value passed from C compiler code is in R0 - compare to a "0" CMP R0, #0 ; value == 0 ?; (If-Then-Else) on next two instructions using equal cond flag ITE EQ

    If the parameter is 0, use the FIOCLR register if it is 1, use the FIOSET register

  • Base + Immediate Offset; STORE if EQ - clear led 1 port bit using GPIO FIOCLR register and mask STREQ R2, [R1,#0x1C] ; if==0, clear LED1 bit; STORE if NE - set led 1 port bit using GPIO FIOSET register and mask STRNE R2, [R1,#0x18] ; if==1, set LED1 bit

    R1 contains 0x2009C020 So these addresses are

    0x2009C020 + 0x1C = 0x2009C03C (FIOCLR) 0x2009C020 + 0x18 = 0x2009C038 (FIOSET)

    R2 contains a bit in position 18

  • LastlyBX LR returns via return address in Link Register

    Note that this code has assumed that the C program is not using any of the other parameter registers (R1, R2, R3) so it didn’t push/pop them

    push {R1,R2,R3}..pop {R1,R2,R3}

  • Experiment TimeSee if you can get the assembly language function

    to light other LEDs by setting different bits in R2. Then try lighting them in different combinations

    (you can have the C++ program just call the function and wait if you want to take over LED4).

    Note that you’ll need to instantiate the other LEDs in the C++ program to initialize them

  • Homework• Develop assembly language routine to take an int passed from C and

    display the low order 4 bits in the LEDs (it will first need to turn them off)

    • There is an example on MBED if you search for it, but you should be able to do it more efficiently with some clever uses of rotate, shift, and masking with AND - study ARMv7 manual

    • If you dig deeper in the manual, you might find it worth understanding the Bit Field Insert/Clear instruction

    • Due next Wednesday — will demo in class on 11/13

    my_leds(11); //0b1011

  • Homework

    • What your routine really has to do is get bits 0, 1, 2, and 3 moved to bits 18, 20, 21, and 22, respectively, of a register, and store that value at location 0x2009C038

    • Use logical AND for masking, ORR for combining, SHL to move

    • Probably a good idea to clear LEDS first (store appropriate constant into 0x2009C03C)

    my_leds(11); //0b1011

  • C Driver#include “mbed.h”extern “C” int my_leds(int value);// Initialize LEDsDigitalOut myled1(LED1);DigitalOut myled2(LED2);DigitalOut myled3(LED3);DigitalOut myled4(LED4);int main () { for (int i = 0; i

  • Looping in AssemblyBranches Make Repetition Possible

  • Initialize

    Test

    Body

    Update

    Initialize

    Test

    Body

    Update

    Return

    ExitExit

    Return

    Pre-test Post-test

  • Initialize

    Test

    Body

    Update

    Initialize

    Test

    Body

    Update

    Return

    ExitExit

    Return

    Pre-test Post-test

    Conditional branch

  • Initialize

    Test

    Body

    Update

    Initialize

    Test

    Body

    Update

    Return

    ExitExit

    Return

    Pre-test Post-test

    Conditional branch

    Uncon-ditional branch

  • Initialize

    Test

    Body

    Update

    Initialize

    Test

    Body

    Update

    Return

    ExitExit

    Return

    Pre-test Post-test

    Conditional branch

    Uncon-ditional branch

    Conditional branch

  • Counting Loops• Need to identify register for counter (e.g., R5)

    • Another register for limit (e.g., R4), or count down to zero

    • Initialize before loop MOV.W R4, #1 | MOV.W R5, #10

    • Test at top (pre-test), in case zero iterations CMP R4, R5 | BGT exit

    • Increment at bottom, after each iteration ADD R4, R4, #1

    • Unconditional branch to top of loop B top

    for (int i = 0; i< 10; i++)

  • Example PUSH {R4, R5} ;get 2 regs to use ;R4 is i, R5 is limit MOV.W R4, #1 ;int i = 1 MOV.W R5, #10 ;Set limit to 10loop_entry CMP R4, R5 ;R4 - R5 (i - limit) BGT loop_exit ;if i > 10 exit ;loop body goes here ADD R4, R4, #1 ;i++ B loop_entry ;Returnloop_exit POP {R4, R5} ;restore regs

  • Nesting• Need additional registers for each loop

    • Can use others for shallow nesting

    • PUSH and POP for deeper nest

    • Inner loop is contained within outer

    • Don’t jump out of loop and back in

    • Use subroutine call if necessary

    • Keep it organized and clean

  • Organizing Loops

    • Check that each loop has its own counter, limit, entry label, exit label

    • Counter for outer loop may be limit for inner loop -- be careful that the inner loop doesn’t change it

    • If a loop has a break, branch only to its exit

    • Comment loops thoroughly, indent them

  • While Loops• Same structure as counting loop, except

    • Update is part of the body (comment it)

    • Condition is more complex

    • May involve computation

    • Condition evaluates to a value that can be compared (e.g., if 0 is exit, BEQ)

    • Arithmetic opcodes (SUB) set flags when they have S appended (SUBS)

  • Repeat Loops• Assumes one iteration -- post-test

    • Starts with entry label, goes right into body

    • Test is at end, branches back to entry

    • Exit is when repeat condition fails

    • Falls through branch to next instruction

    • Good to mark the exit with a label

  • Example PUSH {R4, R5} ;Free regs ;Code to initialize conditionloop_entry ; loop body goes here ; includes condition update

    ;Exit test CMP R4, R5 ;R4 - R5 BNE loop_entry ;R4!=0, returnloop_exit ;Documentation POP {R4, R5} ;Restore regs

  • Experiment

    • Open asm_func.s from last time

    • Delete code between asm_func label and BX LR (PUSH through POP)

    • Insert counting loop for(int = 1, i

  • AREA asm_demo, CODE, READONLY EXPORT my_asmmy_asm PUSH {R1, R2} MOV.W R1, #1 ;int i = 1 MOV.W R2, #10 ;Set limit to 10loop_entry CMP R1, R2 ;R4 - R5 (i - limit) BGT loop_exit ;if i > 10 exit ;loop body goes here ADD R1, R1, #1 ;i++ B loop_entry ;Returnloop_exit POP {R1, R2} BX LR ALIGN END

  • Experiment

    • Turn it into a void function in C

    • Make body empty

    • See how big you have to make the counter to get a one-second delay (may have to switch MOV to LDR R2, =100000000)

    • Have C program turn light on, call function, turn light off

  • Homework Addendum• Your light-setting routine will set the lights and return in under a

    microsecond per value (you could insert a wait(0.5) in the C code for debugging)

    • Use the waiting loop you just built as a subroutine that you call from within your assembly code to make the lights visible for at least half a second before returning to C

    • That means your main subroutine has to PUSH and POP LR in addition to its working registers

  • AREA asm_demo, CODE, READONLY EXPORT my_ledsmy_leds PUSH {R1, R2,…, LR} ; LED-setting code goes here BL wait ; Call to wait POP {R1, R2,…, LR} BX LR ALIGN ; End of my_leds function

    wait ; Start of wait subroutine PUSH {R1, R2} ; Omitted loop code goes here POP {R1, R2} BX LR ; Return from wait ALIGN END

    Overall code structure

  • Term Project• Use MBED features to do something interesting, especially using I/O

    devices

    • Impress the rest of the class

    • Demo will be public, in large conference room, during class, on last day of class

    • Collection of I/O devices available, can get more within reason by sending a request by November 13

    • Note that there are no good local sources

  • Component Requests• Find what you want at Adafruit or Digikey

    • Make sure

    • It is in stock

    • You can find drivers if needed

    • You also list any level converters, H-bridges, amplifiers, transistors, power supplies or connectors, other support circuitry as needed

    • Email link(s) to item(s), specify quantity, and unit price

  • Proposal Due Wednesday

    • Draft for feedback

    • Requires looking at major aspects

    • Starts process of identifying tasks to be done