Reputation: 1573
I am trying to compile a simple Assembly Program with avr-gcc to run on an Attiny85. Unfortunately, the program simply doesn't work. And I get no errors while uploading and compiling. I know that the program itself should work because it works using C. So what am I missing?
Compiling and Uploading:
avr-gcc blinky.S -mmcu=attiny85 -Os -g -o blinky.out
avr-objcopy -O ihex blinky.out blinky.hex
sudo avrdude -p attiny85 -c usbasp -P usb -e -U flash:w:blinky.hex
blinky.S
#define F_CPU 1000000L
#include <avr/io.h>
.section text
.org 0
.global init
rjmp init
init:
ldi r23,0x00
ldi r24,0xFF
out _SFR_IO_ADDR(DDRB), r24
out _SFR_IO_ADDR(PORTB), r23
rjmp main
.org 0x020
.global main
main:
out _SFR_IO_ADDR(PORTB), r24
rjmp main
Output:
Philipps-MacBook-Pro:Desktop philippbraun$ sh script.sh attiny85 blinky.S
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e930b
avrdude: erasing chip
avrdude: safemode: Fuses OK
avrdude done. Thank you.
COMPILING AS ASSEMBLY FILE
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e930b
avrdude: erasing chip
avrdude: reading input file "blinky.hex"
avrdude: input file blinky.hex auto detected as Intel Hex
avrdude: writing flash (46 bytes):
Writing | ################################################## | 100% 0.03s
avrdude: 46 bytes of flash written
avrdude: verifying flash memory against blinky.hex:
avrdude: load data flash data from input file blinky.hex:
avrdude: input file blinky.hex auto detected as Intel Hex
avrdude: input file blinky.hex contains 46 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.03s
avrdude: verifying ...
avrdude: 46 bytes of flash verified
avrdude: safemode: Fuses OK
avrdude done. Thank you.
The following C program compiles successfully!
#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB = 0xFF; // PORTB is output, all pins
PORTB = 0x00; // Make pins low to start
for (;;) {
PORTB = 0xFF; // invert all the pins
//_delay_ms(5000); // wait some time
}
return 0;
}
Upvotes: 1
Views: 5807
Reputation: 25593
First I am wondering that you can assembly with your command line! For me it simply doesn't work!
So what you want to achieve? Compile with stdlib support ( irq jump table, jump to main at start? Or do you want to do it all by hand?
Do it all by hand:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85 -nostdlib
use stdlib to get jump table:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85
If you use it without jump table you should use avr-as instead of avr-gcc!
So I tried your code with the hand crafted version and my assembly was simply empty! Why?
You have a typo:
.section text
is wrong!
Use:
.section .text
My dump looks like that:
00000000 <init>:
0: 8f ef ldi r24, 0xFF ; 255
2: 87 bb out 0x17, r24 ; 23
4: 0d c0 rjmp .+26 ; 0x20 <main>
...
00000020 <main>:
20: 88 bb out 0x18, r24 ; 24
22: fe cf rjmp .-4 ; 0x20 <main>
Nothing blinks here!
Next: Why use .org here? If you add something to init which is larger then 0x020 in code size it will be overridden by main! So simply remove that dirty lines!
#include <avr/io.h>
ldi r23,0x00
ldi r24,0xFF
out _SFR_IO_ADDR(DDRB), r24
main:
out _SFR_IO_ADDR(PORTB), r24
out _SFR_IO_ADDR(PORTB), r23
rjmp main
Results in:
00000000 <__ctors_end>:
0: 70 e0 ldi r23, 0x00 ; 0
2: 8f ef ldi r24, 0xFF ; 255
4: 87 bb out 0x17, r24 ; 23
00000006 <main>:
6: 88 bb out 0x18, r24 ; 24
8: 78 bb out 0x18, r23 ; 24
a: fd cf rjmp .-6 ; 0x6 <main>
And why you have used .global
? nobody references externally on your defined symbols init
and main
.
So if you use a version with stdlib, you only have to export main to make it visible by the start up code. But if you want to do that, there is no way to use init
before main. As I know the avr-libc has no idea about an extra user init method at all.
Upvotes: 2