CS453 Colorado State University ================================================================ Meggy Jr Simple Library and avr-gcc, 8-bit AVR Assembly Language ================================================================ Plan for today avr-gcc tool chain and provided Makefile Meggy Jr Simple library ATmega328p chip avr assembly ----------------- You already have worked with the avr-gcc tool chain and provided Makefile in PA1. http://www.cs.colostate.edu/~cs453/yr2012/MeggyJavaInfo/building-for-meggy.html ----------------- Meggy Jr Simple concepts and their interface See the Meggy Jr RGB Programming Guide (show them on line) http://www.cs.colostate.edu/~cs453/yr2012/MeggyJavaInfo/ProgrammingMeggyJr.pdf LED screen 8x8 grid x coordinate goes from left to right, 0 through 7 y coordinate goes from bottom to top, 0 through 7 Colors are single bytes Auxiliary LEDs SetAUXLEDs( number ); Least significant bit for number represented by left-most LED. Buttons GetButtons() returns a byte. B is represented with least significant bit, value 1. A with 2. Up with 4. Down with 8. Left with 16. Right with 32. Two options, no opinion yet on which is better (1) if (4 & GetButtons()) (2) CheckButtonsDown(); if (Button_Up) Speaker Takes a tone frequency divisor and a duration in milliseconds. -> show the tone definitions in MeggyJrSimple.h and frequency equation Logistics, or Interfaces? - layered on top of Meggy library Color indices appear to be one of the main reasons. - what it adds Color indices Pre-defined tone divisors Nice programming guide. =) - what we add to it delay_ms GetButtons ------------------ ATmega328p chip Terminology http://www.engineersgarage.com/articles/avr-microcontroller, really useful Uses a Harvard Architecture Separate program and data memory Thriving programming community email and website resources http://www.avrfreaks.net/ http://www.arduino.cc/ --------------- Why is it useful to be comfortable with assembly? -it is the target language for compilers -programs for embedded processors are sometimes written in assembly -some of these low-level concepts are needed to implement drivers -useful to understand an example of how data is organized in memory because might have to use a hexdump to do some nasty debugging some day -translating to C avoids the joy of learning how the run-time stack works in detail =================== avr assembly ISA: instruction set architecture, interface machine provides RISC - ld-store architecture -> draw picture of abstraction: memory (data, text, heap, stack), registers, CPU - only load-store operations have access to memory - AVR has some stack architecture features such as push and pop -> draw stack architecture alternative where operations only performed on a stack -------------------- Loads and Stores in r28,__SP_L__ // putting the stack pointer into r29:r28 in r29,__SP_H__ ldd r24, Y+3 // load byte that is 3 bytes from address in r29:r28 // r24 = M[r29:r28 + 3] std Y+1, r24 // store value in r24 to address r29:r28+1 // M[r29:r28 + 1] = r24 ------------------- add r30, r24 // perform some addressing arithmetic into r31:r30 adc r31, r25 ldd r24, Z+0 // load byte at the address in r31:r30 -------------------- Registers http://www.nongnu.org/avr-libc/user-manual/FAQ.html caller saved r18-r27, r30-r31 callee saved r2-r17, r28-r29 Y is 29:28, used for frame pointer Z is 31:30, can be used for other pointers -------------------- Pushes and Pops -> Why do we need a run-time stack? What feature in almost all programming languages requires something like the run-time stack? Dated hint: Fortran 77 does not have this feature. - Talk about what pushes and pops do in AVR. -------------------- Learning AVR with avr-gcc General approach For each language feature, write an example .cpp program, compile it to a .s file, and then figure out the .s file. Examples: PA3bluedot.cpp and PA4buttondot.cpp make PA3bluedot.s make PA4buttondot.s TRICKY BITS (1) Will want to try with optimization for space on and off -> Show how to change the compiler options in the Makefile Remove the -Os flag in CFlags (2) The AVR simulator called MJSIM DOES NOT simulate ALL of the AVR instructions. Your compiler will be required to generate a subset of instructions. See MJSIM for the list of implemented instructions --> Look at the PA4Cyclon.java.s example sent out last night and run it on device. ----------------------------------------------------- Probable AVR instruction subset Show them MJSIM and the available instructions Show them Atmel AVR See http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf for details on these instructions. --> show them these instructions ----------------- main prologue and epilogue __SREG__ = 0x3f __SP_H__ = 0x3e __SP_L__ = 0x3d __tmp_reg__ = 0 __zero_reg__ = 1 .global __do_copy_data .global __do_clear_bss .text .global main .type main, @function main: push r29 push r28 in r28,__SP_L__ in r29,__SP_H__ /* prologue: function */ call _Z18MeggyJrSimpleSetupv /* Need to call this so that the meggy library gets set up */ ... /* epilogue start */ endLabel: jmp endLabel ret .size main, .-main -------------------------------------------- examples of other instructions the simulator will handle pop r24 // pop byte from RTS and put into r24 push r25 // push byte in r25 onto RTS ldi r24, 42 // load constant 42 into r24 ldi r22, lo(352) // load 8 lo bits of 352 into r22 ldi r23, hi(352) // load 8 hi bits of 352 into r23 muls r22, r18 // r1:r0 = r22 * r18 add r22, r18 // r22 = r22 + r18 adc r23, r19 // add with carry, r23 = r23 + r19 + C sub r22, r18 // r22 = r22 - r18 sbc r23, r19 // subtract with carry, r23 = r23 - r19 - C and r22, r18 // r22 = r22 & r18, bitwise AND cp r24, r18 // compare two bytes and set condition codes brne L1 // branch if not equal to label cp r24, r18 // compare lo bits cpc r25, r19 // compare hi bits with carry from lo bits breq L5 // conditional branch, this one is branch if equal tst r24 // sets flags ZNVS jmp L2 // jump to label anywhere in memory L3: // label to jump to, nothing else on this line call funcname // call function, funcname is just a label in r28,__SP_L__ // putting the stack pointer into r29:r28 in r29,__SP_H__ ldd r24, Y+3 // load byte that is 3 bytes from address in r29:r28 // r24 = M[r29:r28 + 3] std Y+1, r24 // store value in r24 to address r29:r28+1 // M[r29:r28 + 1] = r24 ------------------------------ calling convention reference: http://www.nongnu.org/avr-libc/user-manual/FAQ.html - calling convention is interface between caller and callee - callers have to pass parameters to callee - callees have to pass return values to caller - callers and callees have to agree who is storing what registers - stack pointer and frame pointer are used to keep track of the runtime stack Arguments - allocated left to right, r25 to r8 r24, r25 parameter 1, only use r24 if just a byte parameter r22, r23 parameter 2 r20, r21 parameter 3 r18, r19 parameter 4 ... r8, r9 parameter 9 Return values 8-bit in r24 (not r25!), 16-bit in r25:r24, up to 32 bits in r22-r25, up to 64 bits in r18-r25. 8-bit return values are zero/sign-extended to 16 bits by the called function (unsigned char is more efficient than signed char - just clr r25). Arguments to functions with variable argument lists (printf etc.) are all passed on stack, and char is extended to int. Who saves what registers caller saved r18-r27, r30-r31 callee saved r2-r17, r28-r29 Stack pointer: pointer to first available loation on RTS, used for pop and push in e.g.expression evaluation; therefore varies Frame pointer: pointer to a fixed location of stack frame ---------------------------------------- Allocating space on the heap with malloc Library function for malloc(int n): Allocates n consecutive bytes in the heap and returns the address of the first byte allocated. Reference: http://www.nongnu.org/avr-libc/user-manual/malloc.html ------------------------ mstrout@cs.colostate.edu, 2/10/11 updated WB Spr 2012