Embedded System - Arduino |
||
Programming in Assembly
Compile and Uploading with Command Window
Step 1 : Go to the directory where you put the Assembly source code
First go to the directory where the Assembly Code is located (I created a Assmebly name as Blink.S). The content of the directory is as shown below.
C:\Arduino\asm\Blink>dir Volume in drive C is Windows Volume Serial Number is F8D3-F022
Directory of C:\Arduino\asm\Blink
07/27/2016 06:09 PM <DIR> . 07/27/2016 06:09 PM <DIR> .. 07/27/2016 05:25 PM 252 blink.S 1 File(s) 252 bytes 2 Dir(s) 65,290,346,496 bytes free
Step 2 : Comple the source code
Next step is to compile the assembly code. The complier program is avr-as. Since the location of the folder containing the avr-as is not added in the Windows PATH variable, you need to specify the full Path of the program as shown below.
C:\Arduino\C\Blink>"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-as" -g -mmcu=atmega328p -o Blink.o Blink.S
NOTE 1 : The location of the compiler might be different depending on Arduino IDE version and installation directly. So before you try this and find out exact location of the folder. In Windows, you may use Windows File Explorer and search avr-as. In Linux, you may try 'ls -al -R | grep "avr-as"'
After the compliation is complete, check the contents of the folder again and you will notice that following file is created.
C:\Arduino\asm\Blink>dir Volume in drive C is Windows Volume Serial Number is F8D3-F022
Directory of C:\Arduino\asm\Blink
07/27/2016 06:12 PM <DIR> . 07/27/2016 06:12 PM <DIR> .. 07/27/2016 06:12 PM 1,300 Blink.o 07/27/2016 05:25 PM 252 blink.S 2 File(s) 1,552 bytes 2 Dir(s) 65,289,904,128 bytes free
Step 3 : Link the object code
Now link the object file as shown below.
C:\Arduino\asm\Blink>"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-ld" -o Blink Blink.o
Now you have a new file created as shown below.
C:\Arduino\asm\Blink>dir Volume in drive C is Windows Volume Serial Number is F8D3-F022
Directory of C:\Arduino\C\Blink
07/27/2016 06:14 PM <DIR> . 07/27/2016 06:14 PM <DIR> .. 07/27/2016 06:14 PM 1,379 Blink 07/27/2016 06:12 PM 1,300 Blink.o 07/27/2016 05:25 PM 252 blink.S 3 File(s) 2,931 bytes 2 Dir(s) 65,289,900,032 bytes free
Step 4 : Convert the linked file into .hex format
Now you convert the linked file into a binary file that can be directly loaded to the EEPROM of the Arduino board as shown below.
C:\Arduino\asm\Blink>"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-objcopy" -O ihex -R .eeprom Blink Blink.hex
Now you see the new file in hex format created as shown below.
C:\Arduino\asm\Blink>dir Volume in drive C is Windows Volume Serial Number is F8D3-F022
Directory of C:\Arduino\asm\Blink
07/27/2016 06:16 PM <DIR> . 07/27/2016 06:16 PM <DIR> .. 07/27/2016 06:14 PM 1,379 Blink 07/27/2016 06:16 PM 50 Blink.hex 07/27/2016 06:12 PM 1,300 Blink.o 07/27/2016 05:25 PM 252 blink.S 4 File(s) 2,981 bytes 2 Dir(s) 65,290,428,416 bytes free
Step 5 : Upload the hex file into Arduino board
Now the last step is to upload the hex file onto the board and this was the step that gave me a lot of trouble and it took me long time for me to find the solution to make this work. The problem at the beginning turned out to be because I missed out the option -C "C:\Program Files (x86)\Arduino\hardware\tools\avr\etc\avrdude.conf" . So don't forget to specify this option. Also keep in mind that the location of the file avrdude.conf may be different in your environement. Find the exact location of this file first before you try this command. If you are really motivated, open up this file and try to decipher the meaning of the all the information in the file.
C:\Arduino\asm\Blink>"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avrdude" -C "C:\Program Files (x86)\Arduino\hardware\tools\avr\etc\avrdude.conf" -F -V -c arduino -p ATMEGA328P -P COM3 -b 115200 -U flash:w:Blink.hex
NOTE : I am using Arduino UNO R3 and my Arduino board is connected to my Windows PC via COM3 port. If you are using different type of Arduino board and connection is through different COM3 port, you may need to change the variable for -p and -P option in the command above.
If all the options typed in the command line is correct, you will get the print outs as shown below, otherwise you may get some error message. Once you get the print out as shown below, you will see the program running on the board. (In this example, Blink.c has the code blinking the onboard LED connected to PIN 13 on Arduino Uno).
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e950f avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "Blink.hex" avrdude: input file Blink.hex auto detected as Intel Hex avrdude: writing flash (12 bytes):
Writing | ################################################## | 100% 0.02s
avrdude: 12 bytes of flash written
avrdude: safemode: Fuses OK (H:00, E:00, L:00)
avrdude done. Thank you.
Convert o (Object File) into Assembly Code
Step 1 : Create an Arduino Sketch file as shown in the following example
void setup() { Serial.begin(9600); Serial.println("Hello World !");
}
void loop() { }
Step 2 : Go to the folder where *.elf file is located and confirm that you have an elf file in the folder. (If you don't know how to find this location, refer to the section Compile and upload in verbose mode)
C:\Users\Sharetechnote\AppData\Local\Temp\buildbb526efb0f6c38750b56f64014c17ca2.tmp\sketch>dir ...
01/28/2017 12:21 AM <DIR> . 01/28/2017 12:21 AM <DIR> .. 01/28/2017 12:21 AM 633 Serial_01.ino.cpp 01/28/2017 12:21 AM 1,134 Serial_01.ino.cpp.d 01/28/2017 12:21 AM 5,412 Serial_01.ino.cpp.o
Step 3 : Run following command. Then the generated assmebly file will be stored in Serial_01.txt file.
C:\Users\Sharetechnote\AppData\Local\Temp\buildbb526efb0f6c38750b56f64014c17ca2.tmp\sketch>"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-objdump" -D -S Serial_01.ino.cpp.o > Serial_01.txt
Note : Try without '-D' option and see what the difference is
Convert elf into Assembly Code / Extract Assembly Code from elf
Step 1 : Create an Arduino Sketch file as shown in the following example
void setup() { Serial.begin(9600); Serial.println("Hello World !");
}
void loop() { }
Step 2 : Go to the folder where *.elf file is located and confirm that you have an elf file in the folder. (If you don't know how to find this location, refer to the section Compile and upload in verbose mode)
C:\Users\Sharetechnote\AppData\Local\Temp\buildbb526efb0f6c38750b56f64014c17ca2.tmp>dir ...
01/28/2017 12:32 AM <DIR> . 01/28/2017 12:32 AM <DIR> .. 01/28/2017 12:21 AM 569 build.options.json 01/28/2017 12:21 AM <DIR> core 01/28/2017 12:21 AM <DIR> libraries 01/28/2017 12:21 AM <DIR> preproc 01/28/2017 12:21 AM 13 Serial_01.ino.eep 01/28/2017 12:21 AM 61,256 Serial_01.ino.elf 01/28/2017 12:21 AM 5,082 Serial_01.ino.hex 01/28/2017 12:21 AM 6,388 Serial_01.ino.with_bootloader.hex
Step 3 : Run following command. Then the generated assmebly file will be stored in Serial_01.txt file.
C:\Users\CA090406\AppData\Local\Temp\buildbb526efb0f6c38750b56f64014c17ca2.tmp>"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-objdump" -d Serial_01.ino.elf > Serial_01.txt
C:\Users\Sharetechnote\AppData\Local\Temp\buildbb526efb0f6c38750b56f64014c17ca2.tmp>dir ...
01/28/2017 12:32 AM <DIR> . 01/28/2017 12:32 AM <DIR> .. 01/28/2017 12:21 AM 569 build.options.json 01/28/2017 12:21 AM <DIR> core 01/28/2017 12:21 AM <DIR> libraries 01/28/2017 12:21 AM <DIR> preproc 01/28/2017 12:21 AM 13 Serial_01.ino.eep 01/28/2017 12:21 AM 61,256 Serial_01.ino.elf 01/28/2017 12:21 AM 5,082 Serial_01.ino.hex 01/28/2017 12:21 AM 6,388 Serial_01.ino.with_bootloader.hex 01/28/2017 12:32 AM 30,333 Serial_01.txt // Click here to get this file
< Blink > ===============================================================
; turns on an LED which is connected to PB5 (digital out 13)
.equ PORTB, 0x05 .equ DDRB, 0x04
.org 0x0000 jmp main
main: ldi r16,0b00100000 out DDRB, r16 out PORTB, r16
Start: rjmp Start
When you read Arduino Assembly code or AVR technical document, you would see a lot of examples using the character X, Y, Z. These characters are special characters used to implement Pointers. Each of these characters indicates a specific registers as listed below.
X = R26:R27 Y = R28:R29 Z = R30:R31
CBI (Clear Bit in I/O Register)
Syntax : CBI <P>,<b> // Set the bit <b> in the port <P> to be '0' Example :
LDD (Load Indirect with Displacement)
Syntax : LDD <Register>,<Y+d> // RegisterD <- the value stored at the address (Y+d) Example : ldd r30, Y+16 // r30 <- the value stored at the address (Y+16)
Syntax : LDI <Register>,<Constant Value> // Register <- ConstantValue Example : ldi r18, 0x06 // Store the value 0x16 into the register R18
Syntax : MOVW <RegisterD>,<RegisterS> // RegisterD <- RegisterS, 1+RegisterD <- 1+RegisterS Example : movw r28, r24 // r28 <- r24, r29 <- r25
Syntax : SBI <P>,<b> // Set the bit <b> in the port <P> to be '1' Example :
ST (Store Indiret)
Syntax : ST Z,<Register> // (Z) <- Register Example : st Z, r24 // (Z) <- r24
Reference :
[1] Native Assembler Programming on Arduino
|
||